首页 > 解决方案 > ReactJS:为什么将值推送到对象中的状态会删除数据?

问题描述

我已经设置了几个输入字段,其中值进入一个 object input,我试图将它与其他数据一起存储到一个新对象中,但该值正在消失。

在我的handleSubmit函数中,我setNewData(mediaArray)只是将 mediaArray 设置为一个新状态 - 它恰好可以正常工作,但是如果我将 mediaArray 包装到一个 object:setNewData({mediaArray})中,它会删除数据。为什么这样做?

我最终试图这样做:setNewData({...setSomeOtherInfo, mediaArray})所以我可以拥有这个:

newData = {
  info: '',
  description: '',
  mediaArray: [
    {
      input1: '',
      input2: '',  
    },
    {
      input1: '',
      input2: '',  
    },
    {
      input1: '',
      input2: '',  
    },
  ]
} 

零件:

const Screen = props => {

  const [someOtherInfo, setSomeOtherInfo] = useState({
    info: '',
    description: ''
  });
  const [mediaArray, setMediaArray] = useState([]);
  const [newData, setNewData] = useState(null);
  const [input, setInput] = useState({
    input1: '',
    input2: ''
  });

  const handleInput1 = (index, value) => {
    mediaArray[index] = {
      ...mediaArray[index],
      ['input1']: value,
    };
  };

  const handleInput2 = (index, value) => {
    mediaArray[index] = {
      ...mediaArray[index],
      ['input2']: value,
    };
  };

  const handleSubmit = () => {
    setNewData(mediaArray);
  };

  useEffect(() => {

  }, [newData]);

  return (
    <View>
      <TextInput onChangeText={e => handleInput1(index, e)} value={input.input1} />
      <TextInput onChangeText={e => handleInput2(index, e)} value={input.input2} />
    </View>
  );
};

export default Screen;

标签: javascriptarraysreactjsobjectecmascript-6

解决方案


你做错了。

  1. 如果它们链接在一起,您不应该创建这么多状态。您可以创建单个状态并更新多个值。
  2. 你不能用变异的数据设置状态。您必须在再次设置之前克隆它。使用解构来克隆

示例如下:

const Screen = props => {
  const [mediaArray, setMediaArray] = useState([]);
  const [newData, setNewData] = useState(null);
  const [input, setInput] = useState({
    input1: "",
    input2: ""
  });

  const handleSubmit = (name, value) => {
    mediaArray[index] = {
      ...mediaArray[index],
      [name]: value
    };
    setMediaArray(mediaArray);
  };

  return (
    <View>
      <TextInput
        onChangeText={e => handleSubmit.bind(null, 'input1')(index, e)}
        value={input.input1}
      />
      <TextInput
        onChangeText={e => handleSubmit.bind(null, 'input2')(index, e)}
        value={input.input2}
      />
    </View>
  );
};

export default Screen;

如果你有这么复杂的逻辑。创建一个reducer(使用reducer)使其变得简单。


推荐阅读