Javascript 在使用钩子触发操作后,如何重新启动redux状态?

Javascript 在使用钩子触发操作后,如何重新启动redux状态?,javascript,reactjs,react-native,redux,react-hooks,Javascript,Reactjs,React Native,Redux,React Hooks,我试图通过触发调用API的操作来更新Redux中的状态 我已经尝试过使用控制台登录操作和reducer进行调试,以查看状态是否正在更改 API返回一个对象并将其存储到reducer中,它似乎工作正常,但屏幕UI没有重新呈现或更新reducer状态 我尝试使用useState React钩子函数来测试问题是来自我的组件还是分派函数,结果发现问题来自Redux分派钩子 在本例中,当我按下我的ToggleSwitch组件时,该操作触发API并将新值存储到reducer。但是UI端的状态没有更新 这是我

我试图通过触发调用API的操作来更新Redux中的状态

我已经尝试过使用控制台登录操作和reducer进行调试,以查看状态是否正在更改

API返回一个对象并将其存储到reducer中,它似乎工作正常,但屏幕UI没有重新呈现或更新reducer状态

我尝试使用useState React钩子函数来测试问题是来自我的组件还是分派函数,结果发现问题来自Redux分派钩子

在本例中,当我按下我的ToggleSwitch组件时,该操作触发API并将新值存储到reducer。但是UI端的状态没有更新

这是我的密码

减速器:

const light_list = (state: object = {}, action) => {
    if (action.type === C.FETCH_ALL_LIGHTS) {
        state = action.payload;
        return state;
    } else if (action.type === C.CHANGE_LIGHT_STATE) {
        _.merge(state[action.id].state, action.payload);
        return state;
    } else {
        return state;
    }
}
行动:

export const UpdateLightState = (lampID, jsondata) => async (dispatch, getState) => {
    const state = getState();
    const { id }: BridgePairedType = state.pairing_bridge;
    const bridge: ConfigurationTypes = state.bridge_list[id];

    const response = await axios({
        url: `http://${bridge.ipaddress}/api/${bridge.username}/lights/${lampID}/state`,
        method: 'PUT',
        data: jsondata
    });
    if (response && response.data) {
        var payload = {};
        response.data.map((data) => {
            let key = Object.keys(data.success)[0].substring(Object.keys(data.success)[0].lastIndexOf('/') + 1);
            let value = Object.values(data.success)[0];
            payload[key] = value;
        })
        dispatch({
            type: C.CHANGE_LIGHT_STATE,
            id: lampID,
            payload: payload
        })
    }
}
屏幕用户界面:

function ControlBulbScreen() {
    const { colors } = theme;
    const lampID = useNavigationParam('lampID');

    const dispatch = useDispatch();
    const light: LightTypes = useSelector(state => state.light_list);
    const updatelight = useCallback((lampID: string, json: LightUpdateStates) => dispatch(UpdateLightState(lampID, json)), [dispatch]);

    const bordercolor = { borderColor: colors.white }

    return (
        <Block style={styles.container}>
            <Block flex={false} center row space="between" style={styles.header}>
                <Text h1 googlebold>{light[lampID].name}</Text>
                <ToggleSwitch
                    offColor="#DDDDDD"
                    onColor={theme.colors.secondary}
                    onToggle={() => updatelight(lampID, { on: !light[lampID].state.on })}
                    isOn={light[lampID].state.on}
                />
            </Block>
        </Block>
    )
}

const styles = StyleSheet.create({
    container: {
        paddingHorizontal: theme.sizes.base * 2,
        backgroundColor: theme.colors.background 
    },
    header: {
        marginTop: 40
    },
    textControl: {
        textAlign: 'left',
        fontSize: 16
    },
    controlrow: {
        marginTop: 20,
        marginBottom: 10
    },
    thumb: {
        width: 25,
        height: 25,
        borderRadius: 25,
        borderColor: 'white',
        borderWidth: 3,
        backgroundColor: theme.colors.secondary,
    },
    textInput: {
        height: 30,
        borderBottomWidth: .5,
        borderRadius: 0,
        borderWidth: 0,
        color : theme.colors.white,
        textAlign: 'left',
        paddingBottom: 10
    }
});

export default ControlBulbScreen;
函数控制bulbscreen(){
const{colors}=主题;
const lampID=useNavigationParam('lampID');
const dispatch=usedpatch();
常量灯光:LightTypes=useSelector(state=>state.light\u列表);
const updatelight=useCallback((lampID:string,json:LightUpdateStates)=>dispatch(UpdateLightState(lampID,json)),[dispatch]);
const bordercolor={bordercolor:colors.white}
返回(
{light[lampID].name}
updatelight(lampID,{on:!light[lampID].state.on})
isOn={light[lampID].state.on}
/>
)
}
const styles=StyleSheet.create({
容器:{
填充水平方向:theme.sizes.base*2,
背景颜色:theme.colors.background
},
标题:{
玛金托普:40
},
文本控件:{
textAlign:'左',
字体大小:16
},
controlrow:{
玛金托普:20,
marginBottom:10
},
拇指:{
宽度:25,
身高:25,
边界半径:25,
边框颜色:“白色”,
边框宽度:3,
背景颜色:theme.colors.secondary,
},
文本输入:{
身高:30,
边框底部宽度:.5,
边界半径:0,
边框宽度:0,
颜色:theme.colors.white,
textAlign:'左',
垫底:10
}
});
导出默认控件BulbScreen;

我想问题出在你的减速机上。你不应该直接变异你的
状态。我的建议是创建一个新的状态,而不是在每种情况下需要返回的状态

下面的语句将为您执行此任务:
constnewstate={…state}

请尝试以下操作:

const light_list = (state: object = {}, action) => {
    if (action.type === C.FETCH_ALL_LIGHTS) {
        return action.payload;
    } else if (action.type === C.CHANGE_LIGHT_STATE) {
        const newState = {...state};
        _.merge(newState[action.id].state, action.payload);
        return newState;
    } else {
        return state;
    }
}
请进一步阅读文档中的


我希望这有帮助

非常感谢您的详细解释。它现在工作得很好:建议为所有情况添加一个新状态,还是只为更新/删除状态?@FirmanJamal在这些情况下,当您只想更改
状态时。如果
状态没有变化
返回状态
就足够了。在状态中插入一个新对象怎么样?@FirmanJamal如果你想添加新的东西,就不应该改变原始对象。您应该复制并添加新对象。我希望这能澄清问题。