Javascript 不可变js映射存储对象丢失方法

Javascript 不可变js映射存储对象丢失方法,javascript,reactjs,immutability,flux,Javascript,Reactjs,Immutability,Flux,一切正常,直到我运行一个方法将一些对象添加到存储,这将触发视图上的重新渲染。。。问题是,在第一个页面加载时,组件上的存储是一个带有所有方法的映射,在更新之后,当组件重新呈现时,它会丢失这些方法并变成一个普通的js对象,显然组件尝试执行一个存储。例如get(),但失败了:S 这是一个屏幕截图: 还有一些代码: class BlogStore { constructor() { this.bindListeners({ handleBlogs: Actions.UPDATE

一切正常,直到我运行一个方法将一些对象添加到存储,这将触发视图上的重新渲染。。。问题是,在第一个页面加载时,组件上的存储是一个带有所有方法的映射,在更新之后,当组件重新呈现时,它会丢失这些方法并变成一个普通的js对象,显然组件尝试执行一个存储。例如get(),但失败了:S

这是一个屏幕截图:

还有一些代码:

class BlogStore {
  constructor() {
    this.bindListeners({
      handleBlogs: Actions.UPDATE_BLOGS,
      handleBlogPost: Actions.UPDATE_BLOG_POST,
      addMoreBlogs: Actions.ADD_MORE_BLOGS,
    });

    console.log('STORE: state before initialization', this.store);
    /* here is where the state structure is defined */
    this.state = Immutable.Map({
      blogs: {
        blogList: [],
        meta: {
          count: 0,
        },
        currentPage: 1,
      },
      blogPost: []
    });
  }

  /* here is where the state gets modified */
  addMoreBlogs(blogs) {
    console.log('addMoreBlogs executed');
    console.log('STORE: state before convertion to js', this.state);
    console.log('we have to add this to the store', blogs);

    //const currentPage = this.state.blogs.currentPage + 1;

    console.log('STORE: blogList should not be empty', this.state.get('blogs').blogList.concat(blogs.blogList));

    const updatedBlogs = this.state.get('blogs').blogList.concat(blogs.blogList);
    const updatedMeta = this.state.get('blogs').meta;

    console.log('STORE: updatedBlogs', updatedBlogs);
    console.log('STORE, updatedMeta', updatedMeta);

    this.setState(this.state.setIn(
      ['blogs'],
      {
        blogList: updatedBlogs,
        meta: updatedMeta,
        currentPage: 1,
      }
      ));

      console.log('STORE: updated state', this.state);
  }
  ...
和组件:

class BlogsWrapper extends React.Component {
  constructor(props) {
    super(props);

    /* get the store data and transform it to plain js */
    this.state = Store.getState();

    //console.log('BLOGSWRAPPER: state gotten in constructor:', this.state);
    this._onChange = this._onChange.bind(this);
  }

  componentDidMount() {
    Store.listen(this._onChange);

    // if (this.state.get('blogs').isEmpty()) {
    //   this.context.router.push('/blog/not-found');
    //   return;
    // }
  }

  componentWillUnmount() {
    Store.unlisten(this._onChange);

    //console.log('BLOGSWRAPPER: resetting page counter');
  }

  _onChange() {
    //this.setState(Store.getState().toJS());
    this.setState(Store.getState());
    console.log('BLOGSWRAPPER: onchange fired', this.state);
  }**

  ...

有什么帮助吗?我不知道发生了什么,我还尝试在addMoreBlogs方法上重新创建store对象,结果相同。如有任何帮助/建议,将不胜感激。谢谢

我最近也遇到了同样的问题,我认为如果计划用对象修改状态,应该使用
mergeIn
而不是
setIn


检查此项以获得相同的解释。

我最近也遇到了相同的问题,我认为如果计划使用对象修改状态,则应该使用
mergeIn
而不是
setIn

请检查此项以获得相同的解释。

您可以尝试以下方法:

this.setState(this.state.setIn(
  ['blogs'],
  Immutable.formJS({
    blogList: updatedBlogs,
    meta: updatedMeta,
    currentPage: 1,
  })));
显然,这是一个黑客。使用不可变状态时,应避免以这种方式更新所有状态。相反,您需要更新不可变对象的确切字段。这就是为什么Facebook的人建议尽可能保持状态平坦。

你能试试这个吗:

this.setState(this.state.setIn(
  ['blogs'],
  Immutable.formJS({
    blogList: updatedBlogs,
    meta: updatedMeta,
    currentPage: 1,
  })));

显然,这是一个黑客。使用不可变状态时,应避免以这种方式更新所有状态。相反,您需要更新不可变对象的确切字段。这就是为什么Facebook的人建议尽可能保持状态平坦。

很好的方法,改为合并。谢谢我认为它更适合我需要完成的任务。但它并没有解决主要问题,组件仍然接收一个对象而不是MapI。我认为您需要在构造函数中更改为fromJS而不是immutable.map。这就是我在JSBinExampleNice方法中所做的,更改为mergeIn。谢谢我认为它更适合我需要完成的任务。但它并没有解决主要问题,组件仍然接收一个对象而不是MapI。我认为您需要在构造函数中更改为fromJS而不是immutable.map。这就是我在JSBin示例中所做的,这是一个选项,但在这种情况下使用mergeIn是很好的。不需要使用2个API(
fromJS
SetIn
),这是一个选项,但在这种情况下使用mergeIn很好。无需使用2个API(
fromJS
SetIn