Redux未更新组件

时间:2019-07-12 14:22:58

标签: react-native redux react-redux

我在React-Native中是个新手。我正在尝试显示设备列表,然后转到一个设备,转到其信息,更改名称,并使用redux更改所有“屏幕”上的名称,但这没有用。我觉得我在道具,状态和全局状态之间有些失落了。

所有导航,视图和API均可正常运行。 这是我的列表视图:

class DeviceList extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
        };
        this._getDevices();
        // BINDING
        this._goToDevice = this._goToDevice.bind(this);
        this._goToDeviceAdd = this._goToDeviceAdd.bind(this);
    }

    componentDidUpdate() {
        console.log("DEVICE_LIST componentDidUpdate : ");
        console.log(this.props.devices);
    }

    _goToDevice(id = number) {
        this.props.navigation.navigate('DeviceDetail', { idDevice: id })
    }

    _getDevices() {
        restGet('devices')
            .then(data => {
                // REDUX
                const action = { type: "INIT_DEVICE_LIST", value: data.datas };
                this.props.dispatch(action);
                // STATE
                this.setState({
                    isLoading: false
                });
            });
    }

    _displayList() {
        if (!this.state.loading && this.props.devices && this.props.devices.length > 0) {
            return (
                <View style=>
                    <FlatList
                        // data={this.state.devices}
                        data={this.props.devices}
                        keyExtractor={(item) => item.id.toString()}
                        renderItem={({item}) => <DeviceItem device={item} goToDevice={this._goToDevice}
                        />}
                    />
                </View>
            )
        }
    }

    render() {
        return (
            <View style={styles.main_container}>
                {/* LOADING */}
                <Loading loading={this.state.isLoading}/>
                {/* LIST */}
                {this._displayList()}
            </View>
        );
    }
}

// REDUX
const mapStateToProps = (state) => {
    return {
        devices: state.devices
    };
};

export default connect(mapStateToProps)(DeviceList);

这是我的“设备详细信息”屏幕:

class DeviceDetail extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            device: null,
            isLoading: true,
        };
        //
        this._getDevice();
    }

    componentDidUpdate() {
        console.log("DEVICE_DETAIL componentDidUpdate : ");
        console.log(this.props.devices);
    }

    _goToDeviceInfo() {
        this.props.navigation.navigate('DeviceInfo', { deviceId: this.state.device.id })
    }

    _getDevice() {
        restGet('devices/' + this.props.navigation.getParam('idDevice'))
            .then(data => {
                // REDUX
                const action = { type: "UPDATE_DEVICE", value: data.datas };
                this.props.dispatch(action);
                // STATE
                this.setState({
                    device: this.props.devices.find(d => d.id === this.props.navigation.getParam('idDevice')),
                    isLoading: false,
                });
            });
    }

    _displayTile() {
        if (this.state.device) {
            return (
                <View>
                    <Text>{this.state.device.name}</Text>
                    <TouchableOpacity onPress={() => this._goToDeviceInfo()}>
                        <FontAwesomeIcon icon={ faCog } size={ 18 } />
                    </TouchableOpacity>
                </View>
            )
        }
    }

    render() {
        return (
            <View style={styles.main_container}>
                {/* LOADING */}
                <Loading loading={this.state.isLoading}/>
                {/* TILE */}
                {this._displayTile()}
            </View>
        );
    }
}

// REDUX
const mapStateToProps = (state) => {
    return {
        devices: state.devices
    };
};

export default connect(mapStateToProps)(DeviceDetail);

我的设备信息屏幕

class DeviceInfo extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            // device: this.props.navigation.getParam('device')
            // device: this.props.devices.find(d => d.id === this.props.navigation.getParam('deviceId')),
        };
        // BINDING
        this._saveItem = this._saveItem.bind(this);
    }

    componentDidUpdate() {
        console.log("DEVICE_INFO componentDidUpdate : ");
        console.log(this.props.devices);
    }

    _saveItem(name) {
        // DB
        // restPost('devices', {'id': this.state.device.id, 'name': name})
        console.log();
        restPost('devices', {'id': this.props.devices.find(d => d.id === this.props.navigation.getParam('deviceId')).id, 'name': name})
            .then(data => {
                // REDUX
                const action = { type: "UPDATE_DEVICE", value: data.datas };
                this.props.dispatch(action);
        });
    }
    _removeDevice() {
        Alert.alert(
            'Supprimer l\'Appareil',
            'Voulez-vous vraiment supprimer cet Appareil ?',
            [
                {
                    text: 'Annuler',
                    style: 'cancel',
                    onPress: () => console.log('Cancel Pressed'),
                },
                {
                    text: 'Oui, je souhaite le supprimer.',
                    onPress: () => {
                        // REDUX
                        const action = { type: "DELETE_DEVICE", value: this.state.device };
                        this.props.dispatch(action);
                        this.props.navigation.navigate('DeviceList')
                    }
                },
            ],
            {cancelable: false},
        );
    }

    render() {
        // const device = this.state.device;
        const device = this.props.devices.find(d => d.id === this.props.navigation.getParam('deviceId'));
        return (
            <View style={ styles.main_container }>
                <DeviceInfoItem device={device} title={'NOM'} value={device.name} edit={true} saveItem={this._saveItem}/>
                <View style={styles.footer}>
                    <TouchableOpacity style={styles.startButton} onPress={() => this._removeDevice()}>
                        <FontAwesomeIcon icon={ faTrash } style={styles.footer_element_icon}/>
                        <Text style={styles.footer_element_text}>Supprimer l'Appareil</Text>
                    </TouchableOpacity>
                </View>
            </View>
        );
    }
}

// REDUX
const mapStateToProps = (state) => {
    return {
        devices: state.devices
    };
};

export default connect(mapStateToProps)(DeviceInfo);

我的设备信息项组件

class DeviceInfoItem extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            displayForm: false,
        };
        this.editText = '';
        console.log(this.props);
    }

    componentDidUpdate() {
        console.log("DEVICE_INFO_ITEM componentDidUpdate");
    }

    _displayValue() {
        if (this.props.edit && this.state.displayForm) {
            return (
                <View>
                    <Input
                        placeholder={this.props.title}
                        // value={value}
                        leftIcon={<FontAwesomeIcon icon={ faTag } size={ 10 } />}
                        leftIconContainerStyle={ styles.inputIcon }
                        onChangeText={(text) => {
                            this.editText = text;
                        }}
                    />
                </View>
            );
        } else {
            return (
                <View>
                    <Text style={ styles.title }>{ this.props.title }</Text>
                    <Text style={ styles.value }>{ this.props.value }</Text>
                </View>
            );
        }
    }
    _displayButton() {
        if (this.props.edit) {
            if (!this.state.displayForm) {
                return (
                    <TouchableOpacity style={styles.edit} onPress={() => {
                        this.setState({
                            displayForm: true
                        })
                    }}>
                        <FontAwesomeIcon icon={ faPen } style={ styles.info_icon } size={ 14 } />
                    </TouchableOpacity>
                );
            } else {
                return (
                    <TouchableOpacity style={styles.edit} onPress={() => {
                        this.props.saveItem(this.editText);
                        this.setState({
                            displayForm: false,
                        });
                    }}>
                        <FontAwesomeIcon icon={ faCheck } style={ styles.info_icon } size={ 14 } />
                    </TouchableOpacity>
                );
            }
        }
    }

    render() {
        return (
            <View>
                <View style={ styles.line }>
                    { this._displayValue() }
                    { this._displayButton() }
                </View>
                <Divider style={ styles.divider } />
            </View>
         );
    }
}
export default DeviceInfoItem;

还有我的减速器:


const initialState = {
    devices: []
};

function updateDevices(state = initialState, action) {
    let nextState;

    // CHECK IF DEVICE EXIST
    const deviceIndex = state.devices.findIndex(device => device.id === action.value.id);
    let device = state.devices.find(device => device.id === action.value.id);

    switch (action.type) {
        case 'INIT_DEVICE_LIST':
            console.log('INIT_DEVICE_LIST');
            nextState = {
                ...state,
                devices: action.value
            };
            return nextState || state;

        case 'ADD_DEVICE':
            console.log('ADD_DEVICE');
            nextState = {
                ...state,
                devices: [...state.devices, action.value]
            };
            return nextState || state;

        case 'DELETE_DEVICE':
            console.log('DELETE_DEVICE');
            if (deviceIndex !== -1) {
                nextState = {
                    ...state,
                    devices: state.devices.filter( (item, index) => index !== deviceIndex)
                }
            }
            return nextState || state;

        case 'UPDATE_DEVICE':
            console.log('UPDATE_DEVICE');
            if (deviceIndex !== -1) {
                let d = state.devices;
                d[deviceIndex] = action.value;
                nextState = {
                    ...state,
                    devices: d
                }
            }
            return nextState || state;

        default:
            return state
    }
}

export default updateDevices;

删除设备工作得很好,设备列表中的更新情况也很好。但是名称更新没有用。保存后,我收到了控制台日志('DEVICE_INFO_ITEM componentDidUpdate),但没有('DEVICE_INFO componentDidUpdate)。为什么?

1 个答案:

答案 0 :(得分:0)

在reducer文件夹中创建一个文件index.js并执行以下操作:

import { combineReducers } from 'redux';

import myreducer from './Reducerfile';

export default combineReducers({
  reducer: myreducer
});

然后

// REDUX
const mapStateToProps = (state) => {
    return {
        devices: state.reducer.devices
    };
};

export default connect(mapStateToProps)(DeviceInfo);