Javascript 即使在将更新后的值从父对象传递给子对象之后,也不会呈现子对象

Javascript 即使在将更新后的值从父对象传递给子对象之后,也不会呈现子对象,javascript,reactjs,Javascript,Reactjs,在父组件中,我从服务器接收数据,然后将这些数据映射为jsx格式。在该映射中,我有一个子组件,并尝试将一个值作为属性从父级状态传递给子级,但是,当我更新该值的状态时,不会执行子级的渲染函数 预期行为:作为用户,我看到一个项目列表。如果我点击一个项目,它应该变成选中状态 export class ReactSample extends React.Component { constructor(props){ super(props); this.state = {

在父组件中,我从服务器接收数据,然后将这些数据映射为jsx格式。在该映射中,我有一个子组件,并尝试将一个值作为属性从父级状态传递给子级,但是,当我更新该值的状态时,不会执行子级的渲染函数

预期行为:作为用户,我看到一个项目列表。如果我点击一个项目,它应该变成选中状态

export class ReactSample extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      items: [],
      mappedItems: [],
      selectedIds: [],
      isSelected: false,
      clickedTripId: null
    };

    this.toggleSelection = this.toggleSelection.bind(this);
  }

  componentWillMount(){
    console.log("Component mounting")
  }

  toggleSelection (id, e) {
    if(!_.includes(this.state.selectedIds, id)) {
      this.setState((state) => ({selectedIds: 
state.selectedIds.concat(id)}));
      this.setState(() => ({clickedTripId: id}));
      this.mapItems(this.state.items);
    }
  }

  componentDidMount() {
    const self = this;
    MyService.getItems()
      .then(res => {
        self.setState(() => ({ items: res.allItems }));
        self.setState(() => ({ mappedItems: 
this.mapItems(res.allItems) }));
      }
    )
  }

  mapItems (items) {
return items.map(trip => {
  return (
    <li key={trip.id} onClick={(e) => (this.toggleSelection(trip.id, 
e))}>
      <span>{trip.title}</span>
      <Tick ticked={this.state.clickedTripId}/>
      <span className="close-item"></span>
    </li>
  );
});
  }

  getItems() {

  }

  render() {
    return (
      <div>
        <a className="title">This is a react component!</a>
        <Spinner showSpinner={this.state.items.length <= 0}/>
        <div className="items-container">
          <ul id="itemsList">
            {this.state.mappedItems}
          </ul>
        </div>
      </div>
    );
  }
}


export class Tick extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    console.log('RENDER');
    return (<span className={this.props.ticked ? 'tick display' : 
'tick hide' }></span>);
  }
}
导出类ReactSample扩展React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[],
MappeItems:[],
已选择的数据项:[],
选:错,
clickedTripId:null
};
this.toggleSelection=this.toggleSelection.bind(this);
}
组件willmount(){
控制台日志(“组件安装”)
}
切换选择(id,e){
如果(!\包括(this.state.selectedIds,id)){
this.setState((状态)=>({selectedId:
state.selectedds.concat(id)});
this.setState(()=>({clickedTripId:id}));
this.mapItems(this.state.items);
}
}
componentDidMount(){
const self=这个;
MyService.getItems()
。然后(res=>{
self.setState(()=>({items:res.allItems}));
self.setState(()=>({MappeItems:
这个.mapItems(res.allItems)});
}
)
}
地图项目(项目){
返回items.map(行程=>{
返回(
  • (此.toggleSelection(trip.id, e) )}> {trip.title}
  • ); }); } getItems(){ } render(){ 返回( 这是一个反应组件! 我看到一些问题

    toggleSelection
    中,您没有对mapItems的结果执行任何操作。如果您只是从状态中删除
    MappeItems
    ,而只是在渲染方法中调用
    mapItems
    ,这种错误将更容易避免


    另一个问题是您正在传递
    this.state.clickedTripId
    作为
    勾选的
    属性。我假设您想要传递类似
    this.state.clickedTripId===trip.id

    的内容,正如Ryan已经说过的,问题是,
    MappeItems
    在单击
    切换选择
    时没有更新。从代码
    mapItems
    中可以明显看出,它以jsx格式返回数据。要更新它,我必须调用
    this.setState({mappedItems:this.mapItems(this.state.items)})
    这意味着我调用
    mapItems
    ,然后将结果分配给状态。在这种情况下,我的列表将被更新,
    Tick
    组件将收到
    this.state。单击editEMID
    作为
    Tick
    属性。要使此代码正常工作,还需要解决一个问题: 更新
    this.state.clickedItemId
    后需要更新此映射列表。方法
    setState
    是异步的,这意味着
    this.setState({mappedItems:this.mapItems(this.state.items)})
    只能在更新了
    此.state.clickedItemId
    后调用。要实现此目的,
    setState
    方法可以接收回调函数作为第二个参数。代码段如下:

    toggleSelection (id, e) {
      if(!_.includes(this.state.selectedIds, id)) {
        this.setState((state) => ({
          clickedItemId: id,
          selectedIds: state.selectedIds.concat(id)
        }), () => this.setState({mappedItems: this.mapItems(this.state.items)}));
      }
    }
    
    在这种情况下,在执行
    mapItems
    功能时,此处需要的状态中的所有数据都将被更新:

    mapItems (items) {
      return items.map(item => {
        return (
          <li key={item.id} onClick={(e) => (this.toggleSelection(item.id, e))}>
            <span>{item.title}</span>
            <span>{this.state.clickedItemId}</span>
            <Tick ticked={this.state.clickedItemId === item.id}/>
            <span className="close-item"></span>
          </li>
        );
      });
    }
    
    mapItems(项目){
    返回items.map(item=>{
    返回(
    
  • (this.toggleSelection(item.id,e))}> {item.title} {this.state.clickedItemId}
  • ); }); }
    感谢Ryan的重播。起初,我在渲染函数中进行了映射,但后来我从官方文档中看到,
    渲染
    函数应尽可能保持干净。这就是我移动“映射”的原因但你是对的,我对映射项不做任何处理。我的map类函数返回一个结果,我必须在调用
    切换选择
    函数中的map函数时调用
    设置状态
    ,以更新
    映射项