Рендеринг состояния React Native / Redux Toolkit всегда на шаг отстает

У меня возникли проблемы с управлением состоянием в приложении, которое я создаю с помощью React Native, поэтому я решил попробовать Redux-Toolkit. Посмотрев пару руководств на YouTube, я смог реализовать нужную мне функциональность. К сожалению, похоже, что когда я устанавливаю новое состояние переменной с помощью диспетчеризации, это состояние всегда на один шаг / состояние позади. Например, согласно моему коду, у переменной term есть начальное значение spring. Есть три кнопки (весна, лето и осень). Если я нажму на лето, в предупреждении будет отображаться весна, что является начальным значением, а если я нажму любую из трех кнопок после этого, будет отображаться лето (что было предыдущим состоянием). Отображаемое состояние всегда является предыдущим. Есть ли проблема с моей логикой кода? По сути, три кнопки будут использоваться для изменения фильтра запросов SQLite в зависимости от срока / семестра. Пожалуйста, просмотрите воссоздание проблемы, с которой я столкнулся с моим кодом ниже. Спасибо

TermSlice.js

    import { createSlice } from "@reduxjs/toolkit";
    
    export const termSlice = createSlice({
      name: "termChanger",
      initialState: {
        term: 'Spring'
      },
      reducers: {
        setTerm: (state, action) => {
          state.term = action.payload;
        }
      }
    });
    
    export const { setTerm } = termSlice.actions;
    export default termSlice.reducer;

Store.js

    import { configureStore } from "@reduxjs/toolkit";
    import termSlice from "./TermSlice";
    
    export default configureStore({
      reducer: {
        termChanger : termSlice
      },
    });

Home.js

import React from "react";
import { StyleSheet, View, Button, Text} from "react-native";
import { StatusBar } from "expo-status-bar";

import {useSelector, useDispatch } from "react-redux"
import { setTerm } from "../redux/TermSlice";

export default function Home() {
  const dispatch = useDispatch();
  const { term } = useSelector((state) => state.termChanger);

  return (
      <View style={styles.container}>

        <Button onPress={() => {
          alert(term);
        }} title="Term">Term</Button>

        <Button onPress={() => {
          dispatch(setTerm("Spring"));
          alert(term);
        }} title="Spring">Spring</Button>

        <Button onPress={() => {
          dispatch(setTerm("Summer"));
          alert(term);
        }} title="Summer">Summer</Button>

        <Button onPress={() => {
          dispatch(setTerm("Fall"));
          alert(term);
        }} title="Fall">Fall</Button>

        <StatusBar style="auto" />
      </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

App.js

import React from "react";
import { Provider } from "react-redux"
import store from "./src/redux/Store";
import Home from "./src/screens/Home";

export default function App() {

  return (
    <Provider store={store}>
      <Home />
    </Provider>
  );
}

person ftlauderdale    schedule 17.04.2021    source источник


Ответы (1)


Действие dispatch(setTerm("Spring")) и функции alert(term) вызываются в одном и том же цикле рендеринга, поэтому alert(term) использует значение term до dispatch.

Ваша ловушка useSelector обновляется. Вы можете alert с новым значением, используя ловушку useEffect, которая реагирует на изменения значения term.

Или просто нажмите кнопку «Срок». Эта кнопка получит правильное значение, потому что она также не изменит отображаемое значение term.

export default function Home() {
  const dispatch = useDispatch();
  const term = useSelector((state) => state.termChanger.term);

  useEffect(() => {
    alert(term);
  }, [term]);

  return (
    <View style={styles.container}>
      <Button onPress={() => alert(term)} title="Term">
        Term
      </Button>

      <Button onPress={() => dispatch(setTerm("Spring"))} title="Spring">
        Spring
      </Button>

      <Button onPress={() => dispatch(setTerm("Summer"))} title="Summer">
        Summer
      </Button>

      <Button onPress={() => dispatch(setTerm("Fall"))} title="Fall">
        Fall
      </Button>

      <StatusBar style="auto" />
    </View>
  );
}
person Linda Paiste    schedule 18.04.2021
comment
Вы правы, спасибо. Я использовал предупреждения для отладки и не понимал, что они использовали состояние, когда я нажимал кнопку ... Я предполагал, что они будут использовать состояние после того, как произошла отправка. - person ftlauderdale; 18.04.2021