Redux 不改变值

Redux does not change values

我的 Redux 不改变变量值。我正在尝试测试 Redux,但我真的找不到我做错了什么。现在我只是想记录一个值,但该值不会改变。

这是我的 ReduxActions:

export const TEST_FUNC = 'TEST_FUNC';

export const testFunc = () => {
    
    const theTestingString = "TAG testing redux";

    return {
        type: TEST_FUNC,
        payload: theTestingString
    }
}

在我的 Reducer 中,我给变量一个初始值,在我的 Actions 文件中,我试图更改该值,但是当我 console.log(testRedux) 时,我只得到初始值。这是我的 Reducer:

import { TEST_FUNC } from "../actions/firebaseActions";

const initialState = {
    theTestingString: 'Initial Value',
}

export default function(state = initialState, action) {

        switch(action.type) {
            case TEST_FUNC: 
            console.log("HSKJDKJSKFDBSKJKAJDL")
            return {
                ...state,
                theTestingString: action.payload
            }
        }

        return state;
}

这是我的店铺:

import {createStore, applyMiddleware, combineReducers} from 'redux';
import thunk from 'redux-thunk';
import {composeWithDevTools} from 'redux-devtools-extension';

import firebaseReducer from './reducers/firebaseReducer';

const rootReducer = combineReducers({
    firebaseTest: firebaseReducer
});

const middleware = composeWithDevTools(applyMiddleware(thunk));

export default createStore(rootReducer, middleware);

这里是我尝试记录值的地方:

import { useNavigation } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import {Button, Card, TextInput} from 'react-native-paper';
import { FirebaseContext } from '../../context/FirebaseContext';
import React, {useContext, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';

const initialUserState = {
    userName: 'Nicole Lopez',
    password: '1001008888',
}

export default function LoginScreen() {
    const [disabled, setDisabled] = useState(false);
    const [userState, setUserState] = useState(initialUserState);
    const testRedux = useSelector(state => state.firebaseTest.theTestingString);
    //const fbContext = React.useContext(FirebaseContext);
    const navigation = useNavigation();

    console.log("Logging right away: " + testRedux);

    const onInputChange = (field, value) => {
        setUserState({
            ...userState,
            [field]: value
        })
    }

    useEffect(() => {
        setDisabled(userState.userName.length === 0 || userState.password.length === 0);
    }, [userState.userName, userState.password])

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

                <TextInput
                    mode="outlined"
                    label="Förnamn & Efternman"
                    defaultValue={userState.userName}
                    onChangeText={text => onInputChange("username", text)}
                    right={<TextInput.Icon name="account" onPress={() => {
                    }}/>}
                    style={styles.textInput}/>

                <TextInput
                    mode="outlined"
                    label="Anställningsnummer 100100xxxx"
                    defaultValue={userState.password}
                    right={<TextInput.Icon name="lock"/>}
                    onChangeText={text => onInputChange("password", text)}
                    style={styles.textInput}/>
            </Card>

            <View style={styles.buttonRow}>

                <Button
                    color={disabled ? "gray" : undefined}
                    disabled={disabled}
                    mode={'contained'}
                    icon={'login'}
                    onPress={() => {
                        //console.log("The func: " + testRedux)
                        console.log("The variable: " + testRedux)
                        //console.log(fbContext)
                        //console.log("TAG isUserSignedIn: " + fbContext?.isuserSignedIn)
                        //console.log("TAG testLog:::: " + fbContext?.testLog())
                        //fbContext?.testLog()
                        //console.log("TAG LOGIN BTN PRESSED")
                        //navigation.navigate('HomeScreen')
                    }}>Login</Button>
            </View>
        </View>
  );
}

这是我的 App.js:

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import {StackScreens} from './src/helpers/types';
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import LoginScreen from './src/screens/LoginScreen/LoginScreen';
import HomeScreen from './src/screens/HomeScreen/HomeScreen';
import {doc, getFirestore, onSnapshot, setDoc, Unsubscribe as UnsubscribeFS} from 'firebase/firestore';
import { FirebaseContextProvider, FirebaseContext } from './src/context/FirebaseContext';
import { useContext } from 'react';
import {Provider} from 'react-redux';

import store from './src/redux/Store';


const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <Provider store={store}>
      <Content />
    </Provider>  
  );
}

export const Content = () => {

  const navigationRef = useNavigationContainerRef();
  const firebaseContext = useContext({FirebaseContext});

  return (
    
    <NavigationContainer ref={navigationRef}>
        <Stack.Navigator initialRouteName="LoginScreen">
          <Stack.Screen name="LoginScreen" component={LoginScreen} />
          <Stack.Screen name="HomeScreen" component={HomeScreen} /> 
        </Stack.Navigator>
      </NavigationContainer>
      
  );
}

我是 ReactNative 的新手,我已经尝试过 Context 但我遇到了类似的问题,也许我做错了什么?

您需要向 运行 reducer 发送一个动作。

顶级:

import { useDispatch, useSelector } from "react-redux";

内部组件:

  const dispatch = useDispatch();

当您要更改值时:

dispatch({
  type: TEST_FUNC,
  payload: "TAG testing redux" (or whatever value you want to add to the reducer)
});

现在我只看到 useSelector 从 redux 中提取数据,它只为您提供初始状态,因为您还没有向 redux 发送任何新值。

感谢我在 post 上收到的评论,我找到了答案。在我的登录屏幕中,我添加了:

const dispatch = useDispatch();
const testRedux = useSelector(state => state.firebaseTest.theTestingString);

我添加了一个 useEffect,通过在 useEffect 中调用它来更改字符串的值:

useEffect(() => {
     dispatch(firebaseAction.testFunc());
     console.log("Entering useEffekt")
 }, [dispatch]);

我就是这样记录的。在这里我得到了两个日志中的字符串:

console.log("The variable: ", testRedux)
console.log("The variable with a + : " + testRedux)

这是整个 LoginScreen 文件:

import { useNavigation } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import {Button, Card, TextInput} from 'react-native-paper';
import { FirebaseContext } from '../../context/FirebaseContext';
import React, {useContext, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import * as firebaseAction from '../../redux/actions/firebaseActions';


const initialUserState = {
    userName: 'Nicole Lopez',
    password: '1001008888',
}

export default function LoginScreen() {
    const dispatch = useDispatch();
    const testRedux = useSelector(state => state.firebaseTest.theTestingString);

    //const testRedux = useSelector(state => state.firebaseTest.theTestingString);

    const [disabled, setDisabled] = useState(false);
    const [userState, setUserState] = useState(initialUserState);
    //const testRedux = useSelector(state => state.firebaseTest.theTestingString);
    //const fbContext = React.useContext(FirebaseContext);
    const navigation = useNavigation();


    const onInputChange = (field, value) => {
        setUserState({
            ...userState,
            [field]: value
        })
    }

    useEffect(() => {
        dispatch(firebaseAction.testFunc());
        console.log("Entering useEffekt")
    }, [dispatch]);

    useEffect(() => {
        setDisabled(userState.userName.length === 0 || userState.password.length === 0);
    }, [userState.userName, userState.password])

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

                <TextInput
                    mode="outlined"
                    label="Förnamn & Efternman"
                    defaultValue={userState.userName}
                    onChangeText={text => onInputChange("username", text)}
                    right={<TextInput.Icon name="account" onPress={() => {
                    }}/>}
                    style={styles.textInput}/>

                <TextInput
                    mode="outlined"
                    label="Anställningsnummer 100100xxxx"
                    defaultValue={userState.password}
                    right={<TextInput.Icon name="lock"/>}
                    onChangeText={text => onInputChange("password", text)}
                    style={styles.textInput}/>
            </Card>

            <View style={styles.buttonRow}>

                <Button
                    color={disabled ? "gray" : undefined}
                    disabled={disabled}
                    mode={'contained'}
                    icon={'login'}
                    onPress={() => {

                        console.log("The variable: ", testRedux)
                        console.log("The variable with a + : " + testRedux)
                        //console.log(fbContext)
                        //console.log("TAG isUserSignedIn: " + fbContext?.isuserSignedIn)
                        //console.log("TAG testLog:::: " + fbContext?.testLog())
                        //fbContext?.testLog()
                        //console.log("TAG LOGIN BTN PRESSED")
                        //navigation.navigate('HomeScreen')
                    }}>Login</Button>
            </View>
        </View>
  );
}