反应:我从reducers的编辑状态有一些错误

时间:2018-07-23 06:52:31

标签: javascript reactjs redux react-redux

我的来源:https://codesandbox.io/s/x91zl9v78p

我尝试编辑标题和内容,但是第一次,内容没有被修改,只有标题被修改了。

从第二个开始效果很好。

为什么会出现此错误?

reducers.js:

case UPDATE_POST:
  return state.map(
    post => (post.id === action.id ? Object.assign({}, post, action) : post)
  );

而且,有没有一种方法可以不使用object.assign来使用扩展运算符?

4 个答案:

答案 0 :(得分:2)

之所以会发生这种情况,是因为您的Item组件的结构带有空字符串,因此,当您编辑标题输入时,状态会更新,并且如果您不编辑内容输入,它将保持为空。

components / List / items.jsx

class Item extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isEdit: false,
      title: this.props.title,
      content: this.props.content
    };
  }
  //...
}

并避免Object.assign

reducers / post.jsx

case UPDATE_POST:
  return state.map(
    post => (post.id === action.id ? { ...post, ...action } : post)
  );

这将克隆post个道具,并合并action个道具。

https://codesandbox.io/s/5xpnm9yrrx

答案 1 :(得分:1)

由于您将标题和内容的初始值存储在道具中,因此您需要通过实现

将初始Item组件状态值同步到道具
static getDerivedStateFromProps({ title, content }) {
    return {
      title, content
    }
}

Working demo

否则,如果用户不触摸字段(例如内容),则代码将使用默认状态值,该值为空字符串。

  

而且,有没有一种方法我可以不用   object.assign?

case UPDATE_POST:
  return state.map(
    post => (post.id === action.id ? {...post, ...action} : post)
  );

此外,通过将整个操作分散到帖子中,您正在污染带有附加属性type的帖子对象。考虑使用payload对象代替传递更新的帖子。

export function updatePost(id, title, content) {
  return {
    type: UPDATE_POST,
    payload: {
      id,
      title,
      content
    }
  };
}

然后散布有效载荷

case UPDATE_POST:
  return state.map(
    post => (post.id === action.payload.id ? {...post, ...action.payload} : post)
  );

答案 2 :(得分:1)

因为item.jsx文件中的this.state.titlethis.state.content仅在更改了输入get的情况下才更新,如果其中一个输入未更改,则this.state.title or this.state.content都是空字符串。在将项目添加到列表后,this.props.titlethis.props.content可用,但是this.state.titlethis.state.content最初在组件中定义为“”字符串。因此可以在编辑集this.state.title = this.props.titlethis.state.content = this.props.content上将defaultvalue用作this.props.tile和this.props.content,然后它将起作用。

答案 3 :(得分:0)

Edit wqr4r0wnvw

也许可以通过像这样在args函数中使用它:

export default function Post(state = initialState, {type, ...post}) {

  switch (type) {

    case ADD_POST:
      return [ ...state, post ];

    case REMOVE_POST:
      return state.filter(({ id }) => id !== post.id);

    case UPDATE_POST:
      return state.map( p => (p.id === post.id ? post : p) );

    default:
      return state;
  }
}