为什么 console.log 显示正确的数组但状态错误(ReactJS) [英] Why console.log shows correct array but the state is wrong (ReactJS)

查看:70
本文介绍了为什么 console.log 显示正确的数组但状态错误(ReactJS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个组件,它是公司地址.每个地址都是一个对象,由两个字段地址和地铁组成.(我通过声明 Props 和 State 去掉了一些代码,因为这无关紧要)

I have a component which is address of company. Each address is an object which is consists of two fields address and metro. (I get rid of some code with declaring Props and State because it doesn't matter)

class CompanyAddress extends React.Component<Props, State> {
    constructor(props:Props) {
        super(props);
        this.state = {address:''}
    }

    changeAddress = (text:string) => {
        this.setState({address: text});
        this.props.changeAddress(this.props.index, text, this.state.metro);
    }

    changeMetro = (metro:{id: Number, name: string}) => {
        this.setState({metro:metro});
        this.props.changeAddress(this.props.index, this.state.address, metro.id);
    }

    render() {
        return (
            <View style={styles.container}>
                <TextInput
                    autoCompleteType="name"
                    placeholder={("address " + (this.props.num))}
                    maxLength={50}
                    style={[styles.address, {marginTop: 5}]}
                    onChangeText={(text) => { this.changeAddress(text)}}
                />

                <TouchableOpacity
                    style={styles.address}
                    onPress={() => this.props.navigation.navigate('MetroList', {changeMetro: this.changeMetro})}
                >
                    {this.state.metro ? (
                        <Text style={[styles.metroText, {color: 'black'}]}>
                            {this.state.metro.name}
                        </Text>
                    ) : (
                        <Text style={styles.metroText}>
                            Nearest metro
                        </Text>
                    )}
                </TouchableOpacity>

                {this.props.num != 1 ? (
                    <AntDesign
                        onPress={() => {this.props.removeAddress(this.props.index)}}
                        style={styles.minus}
                        name="minus"
                        size={24}
                        color="black"
                    />
                ) : null}
            </View>
        );
    }
}

我也有带有地址数组和 3 个方法 addAddress、changeAddress 和 removeAddress 的父组件.

I also have parrent component with array of addreses and 3 methods addAddress, changeAddress and removeAddress.

class CompanyAddresses extends React.Component<Props, State> {
    constructor(props:Props) {
        super(props);

        this.state = {
            addresses: [{address: ''}]
        }
    }

    addAddress = () => {
        this.setState({addresses: [...this.state.addresses, {address: ''}]});
    }

    changeAddress = (elemIndex:number, address:string, metro:number) => {
        let addresses = this.state.addresses;

        addresses[elemIndex] = {address: address, metro: metro};
        this.setState({addresses:addresses});
    }

    removeAddress = (elemIndex:number) => {
        const filtered = this.state.addresses.filter((value, index) => {
           return index != elemIndex;
        });

        console.log(filtered);

        this.setState({addresses: filtered})
    }

    render() {
        return (
            <View style={styles.container}>
                {this.state.addresses.map((address:any, index) =>
                    <CompanyAddress
                        changeAddress={this.changeAddress}
                        removeAddress={this.removeAddress}
                        navigation={this.props.navigation}
                        key={index}
                        index={index}
                        num={index + 1}
                    />
                )}
                {this.state.addresses.length < 5 ? (
                    <Button title="add address" onPress={this.addAddress} />
                ) : null}
            </View>
        );
    }
}

addAdress 和 changeAddress 工作良好,但 removeAddress 不行.此方法在渲染后不会渲染正确的地址.

addAdress and changeAddress work well but removeAddress does not. This method doest not render right addresses after render.

例如,我添加了名称为一"、二"和三"的 3 个地址.然后我删除了名称为two"的地址,但我看到了两个名称为one"和two"的地址.

For example, I added 3 addresses with name "one", "two" and "three". Then I removed address with name "two" but I see two adresses with name "one" and "two".

最有趣的是,我在 setState 方法之前在控制台中看到了地址为一"和三"的正确数组.

The most ineteresting thing is the fact that I see correct array with addresses "one" and "three" in console just before setState method.

推荐答案

状态几乎肯定会正确更新.您看到的问题是由于 map 内的 key 是数组的索引.您可以在 docs 中看到使用索引作为 key 不推荐,这是一个主要原因.

The state is almost certainly being updated correctly. The issue you're seeing is due to the fact that your key inside the map is the index of the array. You can see in the docs that using the index as the key is not recommended, and this is a major reason.

如果项目的顺序可能发生变化,我们不建议对键使用索引.这会对性能产生负面影响,并可能导致组件状态出现问题.

We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.

您已经修改了数组,以便索引 2 处的内容现在位于索引 1 处.这导致 react 认为应该只删除第三项,其他都不需要更改.

You've modified the array so that what was at index 2 is now at index 1. This causes react to think that only the third item should be removed, and nothing else needs to change.

这篇关于为什么 console.log 显示正确的数组但状态错误(ReactJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆