状态更新时,文本区域不会更新

时间:2020-11-05 16:54:06

标签: reactjs

我正在尝试获得一种功能,在该功能中可以选择一个下拉选项,并且文本区域将其文本与该选项相匹配。

因此,如果我选择选项1然后键入,请选择选项2,这很明显,所以我键入了其他内容。现在,如果我在选项1和2之间切换,则可以看到为每个选项键入的文本。

我已将textarea的值绑定到对象属性data[selected],但是当此状态值更新时,文本区域不会更新。我做错了什么?

这是我的代码:

(代码沙箱:https://codesandbox.io/s/hardcore-fog-3pibo?file=/src/App.jsx

import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const parentData = ["one", "two", "three"];

  const [selected, setSelected] = useState("two");
  const [data, setData] = useState(
    parentData.reduce((a, b) => ((a[b] = ""), a), {})
  );

  function handleSelect(event) {
    setSelected(event.target.value);
  }

  function handleTextChange(event) {
    let val = event.target.value;
    setData((prev) => {
      prev[selected] = val;
      return prev;
    });

    console.log(data[selected]);
    console.log(selected);
    console.log(val);
  }

  return (
    <div className="App">
      <h1>Selected is: {selected}</h1>
      <select value={selected} onChange={handleSelect} name="" id="">
        {parentData.map((val, i) => {
          return (
            <option key={i} value={val}>
              {val}
            </option>
          );
        })}
      </select>
      <br /> <br />
      <textarea
        onChange={handleTextChange}
        value={data[selected]}
        name="data"
        id=""
        cols="30"
        rows="10"
      ></textarea>
      {console.log("parent render")}
    </div>
  );
}

3 个答案:

答案 0 :(得分:2)

您正在handleTextChange中对对象进行突变。尝试执行以下操作:

setData((prev) => {
      return {
        ...prev,
        [selected]: val
      };
    });

答案 1 :(得分:0)

您需要使用传播运算符,这样,您将添加新值,而不会使状态发生变化。

function handleTextChange(event) {
    let val = event.target.value;
    setData(data => ...data, val)

}

答案 2 :(得分:0)

Yash Joshi的答案是完美的,除了我的解决方案是采用课堂形式。这样我的

<textarea value={this.state.myText} onChange={this.changeMyText} />

不会被更改

someOtherFunction(){
     this.setState({
          myText: this.state.myText + "abcde"
     });
}

相反,解决方案是将其更改为

someOtherFunction(){
     let newtext = this.state.myText + "abcde";
     this.setState({
          myText: newtext;
     });
}

但非常现实的是,仅常规<input/>并不需要此解决方案