【问题标题】:A state being updated even if I don't call setstate React即使我不调用 setstate React 也会更新状态
【发布时间】:2020-01-30 14:22:59
【问题描述】:

(反应 16.8.6) 我的问题是,当变量更改时,即使我不调用任何 setState,它也会自动更改状态。在我分配值的 handleInputChange 中,它会自动更新状态 clientsData 和 addedClientsData 。我只想更新editedClientsData。

代码如下:

1 - 设置状态(点击按钮触发):

getClients(calls) {
axios.all(calls)
    .then(responseArr => {
        let cleanedDate = []
        responseArr.map(el => {
            cleanedDate.push(el.data.data)
        })
        this.setState({
            clientsData: cleanedDate,
            editedClientsData: cleanedDate,
            loading: false
        })
        this.loadDataChart()
    });
}

2 - 加载输入字段

render(){
    return (...
        this.state.editedClientsData.map(this.renderInput)
    ...)
}

renderInput = (client, i) => {
    const { activeYear } = this.state
    return (<tr key={client.id}>
        <td>{client.name}</td>
        <td><Input
            type="number"
            name={client.id}
            id="exampleNumber"
            placeholder="number placeholder"
            value={client.chartData[activeYear].r}
            onChange={this.handleInputChange}
        /></td>
        <td>{client.chartData[activeYear].x}</td>
        <td>{client.chartData[activeYear].y}</td>
    </tr>
    )
}

handleInputChange(event) {
    let inputs = this.state.editedClientsData.slice();
    const { activeYear } = this.state
    for (let i in inputs) {
        if (inputs[i].id == event.target.name) {
            inputs[i].chartData[activeYear]['r'] = parseFloat(event.target.value)
            console.log(inputs)
            // this.setState({ editedClientsData: inputs })
            break;
        }
    }
}

我尝试分配一个固定号码 我试图保存为 const {clientsData} = this.state ,更新editedClientsData 和 this.setState({clientsData})

所有这些测试都失败了。希望对您有所帮助,谢谢!

【问题讨论】:

  • 您的for .. in 循环没有意义,您是否尝试修改数组中的每个值?
  • 其实这是最后一次测试..第一个版本没有循环,只有let { editedClientsData } = this.stateconst { clientsData, activeYear } = this.stateeditedClientsData[index].chartData[activeYear][data] = parseFloat(event.target.value)但是这段代码也失败了..我得到了同样的错误结果。跨度>
  • 是的,因为如果您使用索引,那么您将尝试更新数组中的所有项目。那么你怎么知道哪个项目需要编辑呢?

标签: javascript reactjs


【解决方案1】:

getClients 函数中,您将相同的数组cleanedDate 分配给状态的两个道具(clientsDataeditedClientsData)。

两个属性都指向同一个数组。因此编辑将反映到这两个属性。现在,假设数组包含对象,因此使用slice 复制数组也将不起作用,因为两个不同的数组都包含对相同数据的引用。考虑下面的例子:

var a = [{prop: 1}];
var b = a.slice();
var c = a.slice();
console.log(c == b); // false
b[0].prop = 2;
console.log(b[0].prop); // 2
console.log(c[0].prop); // also 2, because slice does shallow copy.

在这种情况下,您需要深度复制数据,因此不会重复引用。您可以为此使用 Lodash 实用程序,也可以为此创建自己的实用程序。

【讨论】:

  • 谢谢萨利姆!你的回答解决了我的问题。最终的解决方案是这个,使用 Lodash getClients(calls) { axios.all(calls) .then(responseArr =&gt; { let cleanedDate = [] responseArr.map(el =&gt; { cleanedDate.push(el.data.data) }) this.setState({ clientsData: cleanedDate, editedClientsData: _.cloneDeep(cleanedDate), loading: false }) this.loadDataChart() }); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多