简体   繁体   English

为什么 console.log 显示正确的数组但 state 是错误的(ReactJS)

[英]Why console.log shows correct array but the state is wrong (ReactJS)

I have a component which is address of company.我有一个组件是公司地址。 Each address is an object which is consists of two fields address and metro.每个地址是一个 object,它由两个字段地址和地铁组成。 ( I get rid of some code with declaring Props and State because it doesn't matter ) 我通过声明 Props 和 State 摆脱了一些代码,因为这无关紧要

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>
        );
    }
}

I also have parrent component with array of addreses and 3 methods addAddress, changeAddress and removeAddress.我也有带有地址数组和 3 个方法 addAddress、changeAddress 和 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 and changeAddress work well but removeAddress does not. addAdress 和 changeAddress 运行良好,但 removeAddress 不行。 This method doest not render right addresses after render.此方法在渲染后不会渲染正确的地址。

For example, I added 3 addresses with name "one", "two" and "three".例如,我添加了名为“一”、“二”和“三”的 3 个地址。 Then I removed address with name "two" but I see two adresses with name "one" and "two".然后我删除了名称为“二”的地址,但我看到了两个名称为“一”和“二”的地址。

The most ineteresting thing is the fact that I see correct array with addresses "one" and "three" in console just before setState method.最有趣的是,我在 setState 方法之前在控制台中看到正确的数组,地址为“一”和“三”。

The state is almost certainly being updated correctly. state 几乎可以肯定正在正确更新。 The issue you're seeing is due to the fact that your key inside the map is the index of the array.您看到的问题是由于您在map中的key是数组的索引。 You can see in the docs that using the index as the key is not recommended, and this is a major reason.您可以在文档中看到不建议使用索引作为key ,这是一个主要原因。

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.这会对性能产生负面影响,并可能导致组件 state 出现问题。

You've modified the array so that what was at index 2 is now at index 1 .您已经修改了数组,以便索引2处的内容现在位于索引1处。 This causes react to think that only the third item should be removed, and nothing else needs to change.这会导致 react 认为只有第三项应该被删除,其他任何东西都不需要改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM