【问题标题】:Redux does not update the view after the reducerRedux 在 reducer 之后不更新视图
【发布时间】:2016-03-17 20:03:22
【问题描述】:

已解决:字段形式的 defaultValue 不是我想的那样。

我不知道我在做什么[这里是化学狗图片]。

我的组件名为 loadForm,并通过 thunk 操作从 API 调用加载数据:

class loadForm extends Component {
  constructor(props) {
   super(props);
  }
  /*  Loads data to the form */
  componentDidMount() {
    let action = getAppoThunk(this.props.routeParams.id);
    this.props.dispatch(action);
    console.log('DidMount  appoArray>>'+ JSON.stringify(this.props.appo));
 }

componentWillReceiveProps(nextProps) {
  if (Object.keys(nextProps.appoArrayProp).length  !=  Object.keys(this.props.appoArrayProp).length ) {
  console.log('WWWW  NOT THE SAME nextProps  >>'+ JSON.stringify(nextProps.appo));
  console.log('WWWW  NOT THE SAME thisProps  >>' + JSON.stringify(this.props.appo));
  let action = getAppoThunk(this.props.routeParams.id);
  this.props.dispatch(action);  // thunk middleware dispatch
} else {
  console.log('ARE THE SAME this.props.appo>>' + JSON.stringify(this.props.appo));
}

}

渲染:

   return(
     <form onSubmit={this.handleSubmit}>
      <label htmlFor="for_owner">Eingentümer (owner):</label>
      <input name="owner" defaultValue={this.props.appo.owner} />
    </form>
  );

this.props.appo 实际上已更新,但视图没有改变:

更新

非常感谢大家的帮助,从一开始我的减速器就是:

    case RECEIVE_ONE_APPO
        Object.assign({}, state, {
         appArrayPop: action.appArrayPop
      });

为了降低复杂性,我删除了数组选项,将其替换为一个简单的字符串,此外,我删除了所有其他减速器,所以我的减速器现在只是:

  const initialState = {
      eigentumer:  'initial'  // owner 
   };

  const appo_rdcer = (state = initialState, action) => { 
     switch (action.type){
      case RECEIVE_ONE_APPO:
         return Object.assign({}, state, {
            eigentumer: action.eigentumer
          });

然后我注意到一些奇怪的东西:

return (
    <div id="responsive" className="modal hide fade" tabIndex="-1" >
      <Modal aria-labelledby='modal-label'
        style={modalStyle}
        backdropStyle={backdropStyle}
        show={this.state.showModal}
      >
      <Modal.Header>
         <Modal.Title>Modal Überschrift 1 --> {this.props.eigentumer}  </Modal.Title>
      </Modal.Header>
        <Modal.Body>
          <form onSubmit={this.handleSubmit}>
            <label htmlFor="for_owner">Eigentümer: 2 --> {this.props.eigentumer} </label>
            <input className="form-control" id="for_owner" name="owner" defaultValue={this.props.eigentumer} />
        </form>
      </Modal.Body>
      <Modal.Footer>
         <Button onClick={() => browserHistory.push('/appointments')}>Close</Button>
         <Button bsStyle="primary">Änderungen speichern</Button>
      </Modal.Footer>
    </Modal>
  </div>
  );

结果:

所以,{this.props.eigentumer} 在位置 1 和 2 中更新,但不在 defaultValue={this.props.eigentumer} 这就是视图没有更新的原因。现在我需要read this 知道为什么会这样。

非常感谢您的帮助。

【问题讨论】:

  • 很高兴你知道了。关于 defaultValue 的注释,这是 React 的说法“在第一次渲染时填充此输入,但不要将其视为动态值”。如果你使用 value 代替,那么你很好,但是你还需要一个 onChange 处理程序来告诉 React 当你在输入字段中写入时要做什么。那么答案是否被接受?
  • 是的,我改成了: 我可以用一个方法处理所有的 onChange:handleChange(name, event)

标签: javascript reactjs redux redux-thunk


【解决方案1】:

appoArrayProp怎么改?如果您正在处理同一个对象,并且只是删除或添加键,nextPropsthis.props 将指向同一个对象,并且它们将始终相等。是的,它并不直观,但就是这样。

假设你有对象appoArrayProp

appoArrayProp = {
  "foo": 1,
  "bar": 2
}

如果您通过简单地添加或删除属性来更改它,nextProps.appoArrayPropthis.props.appoArrayProp 将都指向同一个对象:

appoArrayProp = {
  "foo": 1,
  "bar": 2,
  "newProp": 3
}

并且 Object.keys().length 比较将始终返回 true。解决方案是创建一个新对象,复制当前 appoArrayProp 的属性,在新对象中添加或删除键,然后将其作为属性传递:

appoArrayProp = Object.assign({}, appoArrayProp)
/* Do changes to appoArrayProp and render component */

【讨论】:

  • 不直观,除非您根本没有阅读任何文档。它是 redux 的核心,不可变对象,你必须返回新对象。除了那个小牛肉,考虑到 OP 没有显示他们的减速器,很好的猜测:p
  • nextProps.appoArrayProp 和 this.props.appoArrayProp 指向同一个对象。处理不可变原则很重要。 reducer 必须返回一个新的状态对象,而不是相同的修改状态。如果你想使用原生对象,你可以使用 Object.assign 来实现它,或者像 Immutable.js 这样的外部库(这个非常有用,但它会生成非常复杂的对象,很难检查)
  • @JuanMendes 我们都至少犯过一次这个错误:D
  • @dannyjolie 我希望最多一次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 2019-07-28
  • 2022-01-05
  • 1970-01-01
  • 2019-07-18
  • 2018-09-27
  • 2018-08-04
相关资源
最近更新 更多