编辑不可变状态项

时间:2017-06-18 11:24:00

标签: javascript reactjs

我正在尝试更新一些不可变数据。但是,我做错了,它不起作用。

我的理解是,我需要传递一个唯一的(例如key),以便它知道要更新的状态中的哪个项目。但这可能是错的,我想以正确的方式做到这一点。我尝试了不变性助手,但没有成功。

我还想在不可变数组中更新/添加/删除嵌套项。

我把它放在codeSandbox中以方便https://codesandbox.io/s/mz5WnOXn

class App extends React.Component {
  ...
  editTitle = (e,changeKey) => {
   this.setState({
    movies: update(this.state.movies, {changeKey: {name: {$set: e.target.value}}})
  })
    console.log('Edit title ran on', key)
  };

  ...

  render() {
  ...
    return (
      <div>
        {movies.map(e => {
          return (
            <div>
              <input key={e.pk} onChange={this.editTitle} value={e.name} changeKey={e.pk} type="text" />
              With genres:
              {e.genres.map(x => {
                return (
                  <span key={x.pk}>
                    <input onChange={this.editGenres} value={x.name} changeKey={x.pk} type="text" />
                  </span>
                );
              })}
            </div>
          );
        })}
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:1)

一些事情,
1.通过查看您的数据,我看不到任何pk属性可能是一个错字(您是否尝试使用id属性?)。
2. key道具应位于map函数每次迭代时返回的根元素上。
3.您不能只将原生属性添加到原生Html元素,而是可以使用data-*之类的data-changeKey并通过e.target.getAttribute('data-changeKey')

访问它

这样的事情:

import { render } from 'react-dom';
import React from 'react';
import { reject, pluck, prop, pipe, filter, flatten, uniqBy } from 'ramda';
import { smallData } from './components/data.js';
import './index.css';
import Result from './components/Result';
import update from 'react-addons-update';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      movies: smallData.movies,
      selectedFilters: {},
      searchQuery: '',
    };
  }
  editTitle = (e) => {
    const attr = e.target.getAttribute('data-changeKey');
    this.setState({
      movies: update(this.state.movies, {
        // what are you trying to do here?
        //changeKey: { name: { $set: e.target.value } },
      }),
    });
    console.log('edit title ran on', attr);
  };

  onSearch = e => {
    this.setState({
      searchQuery: e.target.value,
    });
  };

  render() {
    const { movies } = this.state;
    return (
      <div>
        {movies.map((e, i) => {
          return (
            <div key={i}>
              <input
                onChange={this.editTitle}
                value={e.name}
                data-changeKey={e.id}
                type="text"
              />
              With genres:
              {e.genres.map((x,y) => {
                return (
                  <span key={y}>
                    <input
                      onChange={this.editTitle}
                      value={x.name}
                      data-changeKey={x.id}
                      type="text"
                    />
                  </span>
                );
              })}
              Add new genre:
              <input type="text" />
            </div>
          );
        })}
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

答案 1 :(得分:0)

索引是update所需要的,以便知道要更改哪些数据。

首先,确保您的地图正在创建索引:

{movies.map((e,index) => {
return (
            <input key={e.pk} onChange={e => this.editTitle(e, index)} value={e.name} >
...

然后将索引传递给immutability-helper update,如下所示: 到:

  editTitle = (e, index) => {
   this.setState({
    movies: update(this.state.movies, {[index]: {name: {$set: e.target.value}}})
  })