【问题标题】:Editing immutable state items编辑不可变状态项
【发布时间】:2017-06-18 11:23:59
【问题描述】:

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

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

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

为了方便起见,我把它放在了一个代码沙箱中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>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案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'));
    

    【讨论】:

    • 谢谢。正确,PK 不是不是我的数据。我发现我可以改用index,并在上面提供了答案。不知道哪个更好
    【解决方案2】:

    索引是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}}})
      })
    

    【讨论】:

      猜你喜欢
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 2020-11-12
      • 1970-01-01
      • 2018-11-06
      相关资源
      最近更新 更多