使用<select>设置状态

时间:2018-01-08 20:43:45

标签: reactjs

我映射了状态中的对象数组,并返回包含每个索引的信息的单独div元素。我试图找出最佳方式(或根本没有)将选项列表附加到每个元素,并根据所选内容更新状态。例如,如果索引1的名称是&#34; hannah&#34;并且用户选择&#34; Terry,&#34;我想将索引1的名称更改为&#34; terry。&#34; 这是我到目前为止的代码: &#13; &#13; class App扩展了React.Component {&#13;   state = {&#13;     项目:[]&#13;   };&#13;   componentDidMount(){&#13;     this.setState({&#13;       项目:[&#13;         {&#13;           名称:&#34; jacob&#34;,&#13;           头发:&#34;棕色&#34;,&#13;           性别:&#34;男性&#34;&#13;         },&#13;         {&#13;           名字:&#34; hannah&#34;,&#13;           头发:&#34;棕色&#34;,&#13;           性别:&#34;女性&#34;&#13;         }&#13;       ]&#13;     });&#13;   }&#13;   handleChange = e =&gt; {&#13;     var x = Object.assign({},this.state);&#13;   };&#13;   render(){&#13;     const {items} = this.state;&#13;     回归(&#13;       &LT; DIV&GT;&#13;         {items.length&amp;&amp;&#13;           items.map((item,index)=&gt;(&#13;             &lt; div className =&#34; row mt-5&#34;键= {索引}&GT;&#13;               &lt; Item item = {item} handleChange = {this.handleChange} /&gt;&#13;             &LT; / DIV&GT;&#13;           ))}&#13;       &LT; / DIV&GT;&#13;     );&#13;   }&#13; }&#13; &#13; const Item =({item,handleChange})=&gt; (&#13;   &lt; div className =&#34; col&#34;&gt;&#13;     &lt; div className =&#34; mt-5&#34;值= {item.name}&GT;&#13;       {item.name}&#13;     &LT; / DIV&GT;&#13;     &lt; select onChange = {handleChange}&gt;&#13;       &lt; option value =&#34; jacob&#34;&gt; Jacob&lt; / option&gt;&#13;       &lt; option value =&#34; hannah&#34;&gt; Hannah&lt; / option&gt;&#13;       &lt; option value =&#34; tom&#34;&gt; Tom&lt; / option&gt;&#13;       &lt; option value =&#34; kim&#34;&gt; Kim&lt; / option&gt;&#13;       &lt; option value =&#34; terry&#34;&gt; Terry&lt; / option&gt;&#13;     &LT; /选择&GT;&#13;   &LT; / DIV&GT;&#13; );&#13; &#13; ReactDOM.render(&lt; App /&gt;,document.getElementById(&#34; root&#34;));&#13; &lt; script src =&#34; https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"&gt;&lt; / script&gt;&#13; &lt; script src =&#34; https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"&gt;&lt; / script&gt;&#13; &lt; div id =&#34; root&#34;&gt;&lt; / div&gt;&#13; &#13; &#13; 我通过将x设置为状态的副本来启动handleChange fx,这样我以后可以间接更新它。但是一旦我这样做,我就意识到我不知道如何在功能上定位我想要更新的索引。 感谢Tarik Lefi提供一些启动代码!

1 个答案:

答案 0 :(得分:1)

如果您想传递其他参数,例如indexid,您可以使用内联匿名函数,也可以将Item转换为可以拥有的class组件它是自己的handleChange方法。

这样,如果你传递另一个prop,例如indexId,它可以通过处理程序将其传回。

render块内创建的内联处理程序的问题是在每个render上创建了一个新函数,这可能会导致性能下降。
这就是为什么我更喜欢组件组合方法。

以下是您的代码并进行了一些修改:

class App extends React.Component {
  state = {
    items: []
  };
  componentDidMount() {
    this.setState({
      items: [
        {
          name: "jacob",
          hair: "brown",
          sex: "male"
        },
        {
          name: "hannah",
          hair: "brown",
          sex: "female"
        }
      ]
    });
  }
  handleChange = (value, indexId) => {
    const { items } = this.state;
    const nextItems = items.map((item,index) => {
      if(indexId !== index) return item;
      return {
        ...item,
        name: value
      }
    });
    this.setState({items: nextItems});
  }

  render() {
    const { items } = this.state;
    return (
      <div>
        {items.length &&
          items.map((item, index) => (
            <div className="row mt-5" key={index}>
              <Item item={item} handleChange={this.handleChange} indexId={index} />
            </div>
          ))}
      </div>
    );
  }
}

class Item extends React.Component {
  handleChange = ({target}) => {
    const {handleChange, indexId} = this.props;
    handleChange(target.value, indexId);
  }
  render() {
    const { item } = this.props;
    return (
      <div className="col">
        <div className="mt-5" value={item.name}>
          {item.name}
        </div>
        <select onChange={this.handleChange}>
          <option value="jacob">Jacob</option>
          <option value="hannah">Hannah</option>
          <option value="tom">Tom</option>
          <option value="kim">Kim</option>
          <option value="terry">Terry</option>
        </select>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

修改
作为评论的后续内容:

  

但Item组件中的handleChange方法看起来像外来的   语言给我。你介意解释这里发生了什么,或者   也许链接到一些阅读材料,所以我可以变得更熟悉   用它?

这是ES2015 destructuring syntax

const {handleChange, indexId} = this.props;

与做:

相同
const handleChange = this.props.handleChange;
const indexId = this.props.indexId;

这将从传递给处理程序的事件中提取目标属性:

handleChange = ({target}) => {

而不是这样做:

handleChange = (e) => {
// e.target