Uncaught TypeError: dispatcher.useSyncExternalStore is not a function

Uncaught TypeError: dispatcher.useSyncExternalStore is not a function

我正在尝试使用 useSelector 和 useDispatch 更改 bulma 模型的状态
像这样

      const isState = useSelector((state) => state.isActiveState)

Model.js 是:

import React from 'react'
import "../CSS/Careers.css"
import { useSelector, useDispatch } from 'react-redux';
import { stateCheck } from '../Redux/ActiveState'

export default function Modal() {

      const isState = useSelector((state) => state.isActiveState)
  
      

      const dispatch  = useDispatch()

    
  return (
    <div>
      <div
        style={{ padding: "0rem 0.5rem 0rem" }}
        className={`modal ${isState}`}    //this should change the state to 'is-active'
      >
        <div onClick={() => dispatch(stateCheck())} className="modal-background"></div>
        <div style={{ borderRadius: "1.5rem" }} className="modal-card">
          <header
            style={{
              borderBottom: "1px solid white",
              backgroundColor: "#F2F5FF",
            }}
            className=""
          >
            <div style={{ padding: "17px 19px 20px" }} className="is-flex ">
              <p
                style={{ color: "#7209B7" }}
                className="modal-card-title has-text-weight-semibold"
              >
                Apply For Job
              </p>
              <button
                onClick={() => dispatch(stateCheck())}
                className="delete"
                aria-label="close"
              ></button>
            </div>
          </header>
          <section
            style={{ backgroundColor: "#F2F5FF" }}
            className="modal-card-body"
          >
            <div style={{ padding: "0rem 3rem 0rem" }} className="field">
              <div className="control has-icons-left ">
                <input
                  className="input "
                  // style={{ width: "100%" }}
                  type="text"
                  placeholder="Name"
                />
                <span className="icon is-small is-left">
                  <i className="fas fa-user"></i>
                </span>
              </div>
            </div>

            <div style={{ padding: "0rem 3rem 0rem" }} className="field">
              <div className="control has-icons-left ">
                <input className="input " type="email" placeholder="Email" />
                <span className="icon is-small is-left">
                  <i className="fas fa-envelope"></i>
                </span>
              </div>
            </div>
            <div
              style={{ padding: "0rem 3rem 0rem" }}
              className="file is-medium"
            >
              <label style={{ border: "3px sold #7209B7" }} className="">
                <input className="file-input" type="file" name="resume" />
                <span
                  style={{ backgroundColor: "#F2F5FF" }}
                  className="file-cta"
                >
                  <span className="file-icon">
                    <i
                      style={{ color: "#7209B7" }}
                      className="fas fa-upload"
                    ></i>
                  </span>
                  <span style={{ color: "#7209B7" }} className="file-label">
                    Choose a file…
                  </span>
                </span>
              </label>
            </div>
            <p
              style={{
                padding: "0rem 3rem 0rem",
                fontSize: "15px",
                color: "#fcb01a",
              }}
            >
              Select CV or Resume
            </p>
          </section>
          <footer
            style={{
              borderTop: "1px solid white",
              textAlign: "center",
              height: "20%",
              backgroundColor: "#F2F5FF",
            }}
            className=" has-text-centered"
          >
            <div
              style={{ paddingTop: "9px", textAlign: "center" }}
              className=""
            >
              <button style={{ backgroundColor: "#fcb01a" }} className="button">
                Submit
              </button>
            </div>
          </footer>
        </div>
      </div>

    </div>
  )
}

我的 redux 文件 ActiveState.js 是:

import { createSlice } from '@reduxjs/toolkit'

export const ActiveState = createSlice({
    name: 'isActiveState',
    initialState: {
      value: 0,
    },

    reducers: {
        stateCheck: (state) => {
          // Redux Toolkit allows us to write "mutating" logic in reducers. It
          // doesn't actually mutate the state because it uses the Immer library,
          // which detects changes to a "draft state" and produces a brand new
          // immutable state based off those changes

          if (state.value == 0){ 
               state.value = 'is-active';
            //   console.log(state.value)        


            }
            else{
                state.value = 0;
                // console.log(state.value)        
      

            }

        }
     
      },
    })

    export const { stateCheck } = ActiveState.actions;

    export default ActiveState.reducer;

和store.js是:

import { configureStore } from '@reduxjs/toolkit'
import ActiveState from './components/Redux/ActiveState'

export default configureStore({
  reducer: {

    stateChecker : ActiveState,

  },
})

index.js 是:

import React from 'react';
import ReactDOM from 'react-dom';
import './components/CSS/index.css';
import App from './App';
import store from './store'
import { Provider } from 'react-redux'

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>   
       <App />
    </Provider>

  </React.StrictMode>,
  document.getElementById('root')
);

我已将模型添加到我想使用它的组件并触发我使用的模型:

onClick={() => dispatch(stateCheck())}

调度工作正常我已经检查过console.log

问题是当我尝试通过以下方式获取 redux 状态时:

      const isState = useSelector((state) => state.isActiveState)

我在控制台中收到以下错误:

Uncaught TypeError: dispatcher.useSyncExternalStore is not a function

我正在关注 redux 官方文档:
https://react-redux.js.org/tutorials/quick-start


我已经尝试了一切,检查了导入,检查了语法和关键字,检查了 stackowerflow 上的每个答案,但我仍然收到此错误。

请帮助我,我已经卡在这里快一天了。

完整代码

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import store from './store/store';

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
);

Modal.js

// import '../CSS/Careers.css';
import React from 'react';
import { Button } from 'antd';
import { useSelector, useDispatch } from 'react-redux';
import { stateCheck } from './store/slice';

export default function Modal() {
    const isState = useSelector((state) => state.stateChecker);
    const dispatch = useDispatch();

    console.log(isState);

    return (
        <div>
            <Button onClick={() => dispatch(stateCheck(true))}>Open</Button>
            <div
                style={{
                    padding: '0rem 0.5rem 0rem',
                    // display: isState.value ? 'block' : 'none'
                }}
                className={`modal ${isState.value ? 'is-active' : ''}`} //this should change the state to 'is-active'
            >
                <div onClick={() => dispatch(stateCheck(false))} className='modal-background'></div>
                <div style={{ borderRadius: '1.5rem' }} className='modal-card'>
                    <header
                        style={{
                            borderBottom: '1px solid white',
                            backgroundColor: '#F2F5FF'
                        }}
                        className=''
                    >
                        <div style={{ padding: '17px 19px 20px' }} className='is-flex '>
                            <p style={{ color: '#7209B7' }} className='modal-card-title has-text-weight-semibold'>
                                Apply For Job
                            </p>
                            <button onClick={() => dispatch(stateCheck(false))} className='delete' aria-label='close'></button>
                        </div>
                    </header>
                    <section style={{ backgroundColor: '#F2F5FF' }} className='modal-card-body'>
                        <div style={{ padding: '0rem 3rem 0rem' }} className='field'>
                            <div className='control has-icons-left '>
                                <input
                                    className='input '
                                    // style={{ width: "100%" }}
                                    type='text'
                                    placeholder='Name'
                                />
                                <span className='icon is-small is-left'>
                                    <i className='fas fa-user'></i>
                                </span>
                            </div>
                        </div>

                        <div style={{ padding: '0rem 3rem 0rem' }} className='field'>
                            <div className='control has-icons-left '>
                                <input className='input ' type='email' placeholder='Email' />
                                <span className='icon is-small is-left'>
                                    <i className='fas fa-envelope'></i>
                                </span>
                            </div>
                        </div>
                        <div style={{ padding: '0rem 3rem 0rem' }} className='file is-medium'>
                            <label style={{ border: '3px sold #7209B7' }} className=''>
                                <input className='file-input' type='file' name='resume' />
                                <span style={{ backgroundColor: '#F2F5FF' }} className='file-cta'>
                                    <span className='file-icon'>
                                        <i style={{ color: '#7209B7' }} className='fas fa-upload'></i>
                                    </span>
                                    <span style={{ color: '#7209B7' }} className='file-label'>
                                        Choose a file…
                                    </span>
                                </span>
                            </label>
                        </div>
                        <p
                            style={{
                                padding: '0rem 3rem 0rem',
                                fontSize: '15px',
                                color: '#fcb01a'
                            }}
                        >
                            Select CV or Resume
                        </p>
                    </section>
                    <footer
                        style={{
                            borderTop: '1px solid white',
                            textAlign: 'center',
                            height: '20%',
                            backgroundColor: '#F2F5FF'
                        }}
                        className=' has-text-centered'
                    >
                        <div style={{ paddingTop: '9px', textAlign: 'center' }} className=''>
                            <button style={{ backgroundColor: '#fcb01a' }} className='button'>
                                Submit
                            </button>
                        </div>
                    </footer>
                </div>
            </div>
        </div>
    );
}

slice.js

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

export const ActiveState = createSlice({
    name: 'isActiveState',
    initialState: {
        value: false
    },

    reducers: {
        stateCheck: (state, action) => {
            state.value = action.payload;
        }
    }
});

export const { stateCheck } = ActiveState.actions;
export default ActiveState.reducer;

store.js

import { configureStore } from '@reduxjs/toolkit';
import ActiveState from './slice';

export default configureStore({
    reducer: {
        stateChecker: ActiveState
    }
});

这不是 isActiveState。您应该使用在 configureStore 中指定的 reducer 的名称。 stateChecker

const isState = useSelector((state) => state.stateChecker)

现在 isState 将具有 value

为什么使用“ReactDOM.render”? 您使用 React18 附带的称为 useSyncExternalStore 的技术。你不需要使用 ReactDOM.createRoot(element,options).render(component) 吗?

发生这种情况是因为“react-redux”尚不支持 React 18(React 和 React native)。

将“react-redux”降级到以前的版本将解决您的问题。

对我来说,我将我的 React Native 项目的“react-redux”从“^8.0.1”降级为“^7.2.8”。