反应:props.itemId返回与使用props.itemId的变量不同的值

时间:2019-05-19 00:11:58

标签: reactjs

当前

我有一个子组件ItemField(请参见下面的代码),该子组件从父组件中提取this.props.itemId,并进行检查以查看是否填充了this.props.itemId,并填充了一个新变量this.itemId基于支票,即

itemId = this.props.itemId ? this.props.itemId : "new";

问题

在App上进行排序操作,这些操作在项目列表中移动项目的位置,导致this.props.itemIdthis.itemId返回控制台日志确认的不同值。 this.props.itemId的值正确,但是this.itemId在此位置包含项目的原始值。

ItemField.js

class ItemField extends Component {

  constructor(props) {
    super(props);
    this.state = {
      //temp value of inputs
      }
    }

  componentDidMount() {
    //no actions on did mount
  }

  //issueId to be Updated
  //if "new", then a new issue will be updated
  itemId = this.props.itemId ? this.props.itemId : "new";

  render() {
    console.log("this.props.itemId = " + this.props.itemId); //logs "1111"
    console.log("this.itemId = " + this.itemId); //should log "1111" i.e. same as above, but this doesn't always happen

    return (
      <div
        id={this.itemId}
      >{showValue}
      </div>
    )
  }
}

export default ItemField;

问题

我在上面的脚本中有2条console.log行,在某些情况下(例如,对项目列表进行排序之后)返回不同的值。这些应该始终相同。可能有哪些原因?

注释:

  1. 我尝试将itemId = this.props.itemId ? this.props.itemId : "new"行移至构造函数和componentDidMount中,但这并不能解决问题。
  2. 我不是通过父组件中的所有ItemField进行映射,而是为每个组件显式创建一个组件。 <ItemField value={this.props.item.name} itemId={this.props.item.id} />,其中name是字段值,id是传递给所有字段的itemId。

组件结构

enter image description here

2 个答案:

答案 0 :(得分:1)

MOVE ITEMID内的状态AKA̶̶̶t̶̶̶h̶̶̶i̶̶̶s̶̶̶.̶̶̶s̶̶̶t̶̶̶a̶̶̶t̶̶̶e̶̶̶̶̶̶=̶̶̶{̶̶̶ITEMID:̶̶̶t̶̶̶h̶̶̶i̶̶̶s̶̶̶.̶̶̶p̶̶̶r̶̶̶o̶̶̶p̶̶̶s̶̶̶.̶̶̶i̶̶̶t̶̶̶e̶̶̶m̶̶̶I̶̶̶d̶̶̶}̶̶̶和实施̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶c̶̶̶o̶̶̶m̶̶̶p̶̶̶o̶̶̶n̶̶̶e̶̶̶n̶̶̶t̶̶̶D̶̶̶i̶̶̶d̶̶̶U̶̶̶p̶̶̶d̶̶̶a̶̶̶t̶̶̶e̶̶̶(̶̶̶p̶̶̶r̶̶̶e̶̶̶v̶̶̶P̶̶̶r̶̶̶o̶̶̶p̶̶̶s̶̶̶,̶̶̶ ̶̶̶p̶̶̶r̶̶̶e̶̶̶v̶̶̶S̶̶̶t̶̶̶a̶̶̶t̶̶̶e̶̶̶,̶̶̶ ̶̶̶s̶̶̶n̶̶̶a̶̶̶p̶̶̶s̶̶̶h̶̶̶o̶̶̶t̶̶̶)̶̶̶{̶̶̶ ̶̶̶ ̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶i̶̶̶f̶̶̶ ̶̶̶(̶̶̶t̶̶̶h̶̶̶i̶̶̶s̶̶̶.̶̶̶p̶̶̶r̶̶̶o̶̶̶p̶̶̶s̶̶̶.̶̶̶i̶̶̶t̶̶̶e̶̶̶m̶̶̶I̶̶̶d̶̶̶ ̶̶̶!̶̶̶=̶̶̶=̶̶̶ ̶̶̶p̶̶̶r̶̶̶e̶̶̶v̶̶̶P̶̶̶r̶̶̶o̶̶̶p̶̶̶s̶̶̶.̶̶̶i̶̶̶t̶̶̶e̶̶̶m̶̶̶I̶̶̶d̶̶̶)̶̶̶ ̶̶̶{̶̶̶ ̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶t̶̶̶h̶̶̶i̶̶̶s̶̶̶.̶̶̶s̶̶̶e̶̶̶t̶̶̶S̶̶̶t̶̶̶a̶̶̶t̶̶̶e̶̶̶(̶̶̶{̶̶̶i̶̶̶t̶̶̶e̶̶̶m̶̶̶I̶̶̶d̶̶̶:̶̶̶t̶̶̶h̶̶̶i̶̶̶s̶̶̶.̶̶̶p̶̶̶r̶̶̶o̶̶̶p̶̶̶s̶̶̶.̶̶̶i̶̶̶t̶̶̶e̶̶̶m̶̶̶I̶̶̶d̶̶̶}̶̶̶)̶̶̶ ̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶}̶̶̶ ̶̶ ̶̶ ̶̶̶ ̶̶̶ ̶̶̶ ̶̶̶}̶̶̶̶̶̶

为什么您甚至还需要诚实的itemId?只需直接使用道具即可。

 return (
  <div
    id={this.props.itemId || 'new' }
  >{showValue}
  </div>
)

答案 1 :(得分:1)

它一次运行不会更新,以确保两者始终移动相同的值

itemId = this.props.itemId ? this.props.itemId : 'new';

将其呈现或保存为状态,并使用getDerivedStateFromProps更新该值。

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script type="text/babel">
class ItemField extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      //temp value of inputs
      itemId: '',
    };
  }

  componentDidMount = () => {
    //no actions on did mount
    this.setState({
      itemId: this.props.itemId ? this.props.itemId : 'new'
    })
  }


  //issueId to be Updated
  //if "new", then a new issue will be updated

  static getDerivedStateFromProps = (props, state) => {
    // compare props with state data
    // if they are not equal return props
    // or return null
    // more info here https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
    
    if (props.itemId !== state.itemId) {
      return props;
    }
    return null;
  }

  render() {
    console.log('this.props.itemId = ' + this.props.itemId); //logs "1111"
    console.log('this.state.itemId = ' + this.state.itemId); //should log "1111" i.e. same as above, but this doesn't always happen

    return <div id={this.itemId}>{'showValue'}</div>;
  }
}

class App extends React.Component {

  state = {
    id: 1111
  }

  render() {
    return (
      <div>
        <button onClick={() => this.setState({ id: 2233 })}>Update ID</button>
        <ItemField value={'James'} itemId={this.state.id} />
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>