即使应用程序状态在商店中发生变化,页面组件也不会再次呈现

时间:2021-03-19 18:47:14

标签: reactjs react-redux

当我更新商店的状态时,我同时使用 react-router 和 redux。组件不会重新渲染,因此重定向不起作用。

这是我的代码。

店铺代码:

import { configureStore } from '@reduxjs/toolkit'
import {signInWithPhoneNumber} from '../../modules/auth/actions/authSlice'

const store = configureStore({
  reducer: {
    auth: signInWithPhoneNumber
  }
})

export default store

我正在商店路过

import AppRouting from "./config/routes"
import store from "./store/store"
import firebase from "firebase"
import firebaseConfig from "../config/firebase-config"

function renderUI() {
  ReactDOM.render(
    <Provider store={store}>
      <BrowserRouter>
        <AppRouting />
      </BrowserRouter>
    </Provider>
    ,
    document.querySelector("#root"))
}

我把这个开关组件放在一个 BrowserRouter 中

import { Route, Switch } from "react-router-dom"
import React from "react"
import Login from "../pages/login"
import SignUp from "../pages/sign-up"
import ConfirmPhone from "../pages/confirm-number"

function AuthRoutes(props) {
    
    return (
        <Switch>
            <Route exact path="/">
                <Login />
            </Route>
            <Route exact path="/confirmPhone">
                <ConfirmPhone />
            </Route>
        </Switch>
    )
}

在发送验证码后的登录页面中,我必须加载将用户重定向到 /confirmPhone 路径的 ConfirmPhone 组件。

import React, { useEffect, useState } from "react"
import { Redirect } from "react-router-dom"
import M from 'materialize-css';
import Header from "../components/header"
import Button from "../../../components/Button"
import Dialog from "../../../components/Dialog"
import InputText from "../../../components/TextInput"
import truncateString from "../lib/truncateString"
import { onTextChange, onSubmitForm, onSubmitConfirm, openDialogOnLogIn } from "../config/ui-events"
import { useSelector, useDispatch } from "react-redux"
import { selectAuth, signInWithPhoneNumber } from "../actions/authSlice"
import { actions } from "../actions/authSlice"



function Login(props) {
    const [phoneField, setPhoneField] = useState('')
    const [valid, setValid] = useState(2)
    const openDialog = false
    const currentAuth = useSelector(selectAuth)
    const { signInWithPhoneNumber } = actions
    const dispatch = useDispatch()

    function onChangePhone(evt) {
        const inputValue = evt.target.value
        setPhoneField(truncateString(inputValue, 8))
        setValid(onTextChange(evt, inputValue, /\d{8}?/))
    }

    function onSubmit(evt) {
        evt.preventDefault()

        dispatch(signInWithPhoneNumber({ status: 2, session: null }))
    }

    if (currentAuth.status === 2) {
        console.log(currentAuth)
        return (<Redirect to="/confirmPhone" />)
    } else {

        return (
            <section className="login">
                <div className="login__layout">
                    <Header>
                        <h1>Login</h1>
                    </Header>
                    <form>
                        <p>Accede a tu cuenta</p>
                        <InputText id="phone-number"
                            pattern="\d{8}"
                            errorMessage="Incorrect phone format for +505 area code"
                            successMessage="The phone format is correct"
                            helperMessage="Type a phone number of +505 area code"
                            labelText="Telefono"
                            changeHandler={onChangePhone}
                            validationState={valid}
                            value={phoneField} />
                        <div>
                            <Button clickHandler={onSubmit} text="Entrar" classes="login__signIn" />
                        </div>
                        <div id="recaptcha-container" className="login__captcha">

                        </div>
                    </form>
                </div>
            </section>
        )
    }

}

export default Login

当status的status字段变为2时,我需要做重定向而不是再次加载Login组件。

但即使状态发生变化,组件也不会被重新渲染。

谁能帮我看看会发生什么?

在这个文件中,我创建了一个切片来检索我的减速器、动作和选择器。

import { createSlice } from '@reduxjs/toolkit';

const slice = createSlice({
  name: 'auth',
  initialState: {
    value: {
      status: 0
    }
  },
  reducers: {
    signInWithPhoneNumber: (state, action) => {
      alert("authentication will update the store")
      state.auth = action.payload
    }
  },
});

const selectAuth = (state) => state.auth
const signInWithPhoneNumber = slice.reducer
const actions = slice.actions

export { signInWithPhoneNumber, selectAuth, signIn, actions }

reducer 函数 signInWithPhoneNumber 是我用来更新状态的函数。

1 个答案:

答案 0 :(得分:0)

实际上,您的 auth 对象在另一个 auth 对象内,因此您的选择器应如下所示。这是因为当你创建 store 时,你将它包装在 auth 中,然后当你运行 action 时也将 payload 包装在 auth 中。

const selectAuth = (state) => state.auth.auth;
const store = configureStore({
  reducer: {
    auth: signInWithPhoneNumber // wrap inside auth
  }
});

signInWithPhoneNumber: (state, action) => {
  state.auth = action.payload // wrap inside another auth
},