我正在尝试通过触发调用API的操作来更新我的Redux状态。
我尝试使用控制台登录操作和化简器进行调试,以查看状态是否正在更改。
API 返回一个对象并将其存储到化简器中,它似乎工作正常,但屏幕 UI 没有重新呈现或更新化简器状态。
我尝试使用 useState React Hook 函数来测试问题是否来自我的组件或调度函数,结果发现问题来自 Redux 调度钩子。
在这种情况下,当我按下 ToggleSwitch 组件时,该操作会触发 API 并将新值存储到化简器。但是 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;
我想问题出在您的减速器上。您不应该直接改变您的state
。我的建议是创建一个新状态,而不是在每种情况下需要返回的状态。
以下语句将为您完成这项工作:const newState = {...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;
}
}
在文档中进一步阅读有关不可变更新模式的信息。
我希望这有所帮助!