javascript - 正在编辑 Redux 状态而不派发任何操作

标签 javascript reactjs redux

我有一个带有 react + redux 的应用程序,问题出现在编辑表单中。

问题描述

  1. 点击“编辑”编辑文档
  2. 显示编辑表单
  3. 我编辑/删除其中一个值
  4. 我没有保存(发送保存操作),而是返回到任何其他页面而不保存
  5. 然后返回到该对象的描述页面(“编辑”按钮所在的页面)

结果

文档已编辑。

因此,在 Portlets 组件中,当我单击编辑按钮时,我将 setState({isEditing: true}) :

if(this.state.isEditing) {
  return (
    <div className="col-md-12">
      <div className="card">
        <div className="card-content">
          <PortletForm />
        </div>
      </div>
    </div>
  );

然后我打开 <PortletForm />组件,并使用 connect() 再次访问数据:

function mapStateToProps(state, ownProps) {
  let portlet = {};

  const portletId = ownProps.match.params.id;

  if (state.portlets.length > 0) {
    portlet = Object.assign({}, state.portlets.find(portlet => portlet._id === portletId));
  }

  return { portlet: portlet };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(portletActions, dispatch)
  };
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(PortletForm));

这是 constructor()在编辑表单中:

constructor(props) {
    super(props);

    this.state = {
      portlet: this.props.portlet,
      addNewKey: [],
      addNewKeyDisabled: false,
      newKey: '',
      newValue: ''
    };

    ...
}

这是 <input />在调用编辑功能的 jsx 中:

<input
  type="text"
  className="form-control"
  autoFocus={index === 0}
  name={Object.keys(key)}
  value={Object.values(key)}
  onChange={this._updatePortletKey} /> 

_updatePortletKey() ,问题似乎发生的地方:

_updatePortletKey(event) {
    const field = event.target.name;
    let editedDoc = Object.assign({}, this.state.portlet);
    editedDoc._keys.map((elem, index) => {
      const key = Object.keys(editedDoc._keys[index]);
      if(key[0] === field) {
        return editedDoc._keys[index][field] = event.target.value;
      }
    });
    debugger;
    this.setState({ portlet: editedDoc });
  }

所以我创建了一个新对象,并将其修改为状态,经过一些调试后,这是我发现的:

  • 当我访问此功能时 this.props.portlet包含原始对象
  • 在我从映射函数(放置调试器的地方)返回新键之后和编辑状态之前,this.props.portlet 包含已编辑的 key !

我真的不知道还能尝试什么,在这个函数之前我没有触发任何调度或其他东西,但我也尝试了 console.log()里面mapStateToProps()回到未保存的文档后,商店被编辑,我不明白!我还检查了父函数不包含可能同时工作的任何其他函数……什么也没有。

感谢任何帮助。提前致谢!

编辑:这就是this.props.portlet看起来像:

{
    country: "AR"
    dev: true
    slug: "document-name"
    test: false
    version: 2
    _id: "5a798e53f2c5340bb08479f8"
    _keys: [
        { newKey: "new key value" }
    ]
}

最佳答案

这就是为什么建议处理 redux 的方法是 ImmutableJSimmutable-helper 或类似的方法。

否则很容易出错。

这是发生了什么:

// constructor
this.state = {
  portlet: this.props.portlet,  // you put props in the state
}

// change handler
let editedDoc = Object.assign({}, this.state.portlet);
// here a new object is created, but if the value is not primitive, it is by reference.
// this means, while editedDoc and this.state.portlet are different objects, "_key"'s value is shared between these object.

这是我见过很多人犯的错误。此外,调试此类案例也很痛苦。所以请使用辅助库。

如果你坚持使用 es6 来构造新对象,随着嵌套的增加,它可能会变得丑陋。

// example 1
_updatePortletKey(event) {
  const field = event.target.name;

  this.setState({
    portlet: {
      ...this.state.portlet,
      _keys: this.state.portlet._keys.reduce((agg, el) => {
        const key = Object.keys(el); 
        // btw, what are you trying to do here !! (my logic might be slightly off, as I didn't fully understood the transformation, but you get the idea, right?)
        if(key[0] === field) { 
          return [...agg, {...el, [field]: event.target.value}]
        }
        return [...agg,el]
      }, [])
    }
  })

关于javascript - 正在编辑 Redux 状态而不派发任何操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48648736/

相关文章:

javascript - 设置时间倒计时器jquery

javascript - 从 redux 中删除数据并保存滚动位置

javascript - React 状态获取 "corrupted"

javascript - 更新对象数组而不改变

javascript - 如何使用 React 呈现对象列表

javascript - HTML Webpack 插件未创建正确的 index.html 文件

javascript - Redux - 尝试向configureStore添加功能

javascript - 需要帮助清除对话框中的元素 AngularJS

javascript - jQuery - 选择覆盖在图像上的不可见文本,ala GMail PDF 查看器

javascript - 限制 OrbitControls 水平旋转