redux 在React中的主组件中使用use dispatch定义回调

wlsrxk51  于 2023-05-07  发布在  React
关注(0)|答案(1)|浏览(365)

我有一个问题,我无法在React中解决。我的目的是定义一个按钮回调函数,它将设置redux中的状态值,这个回调函数使用dispatch函数,其中的两个值包含两个不同的redux状态。看起来这些说明

//Saving select selected value from redux store
const selectedValue: string|undefined = useSelector((state: RootState) => state.selectedOption);

//2. Save the input value from the redux store
const inputValue: string|null = useSelector((state: RootState) => state.inputTextValue);

在redux中的store的实际初始化之前执行,所以react给了我这个问题---〉“Could not find react-redux context value;请确保组件 Package 在
我试着这样定义它:
App.tsx

import React, { useCallback } from 'react';
import './App.css';
import { Card } from './components/organism/Card';
import { useState } from "react";
import { Context } from './context/Context'
import { imgData } from "./context/Context";
import { Provider, useDispatch, useSelector } from "react-redux";
import StudentExercise from "./components/organism/studentExercise/studentExercise";
import { createStore } from "redux";
import rootReducer from "./redux";
import { composeWithDevTools } from "redux-devtools-extension";
import { optionsArray } from "./redux/reducers/SelectedOption/selectedOption";
import {
  setBirthYear,
  setCourse,
  setName,
  setSurname,
  setTutor
} from "./redux/actions";

export type RootState = ReturnType<typeof store.getState>

// todo: cercare metodo non deprecato
const store = createStore(rootReducer, composeWithDevTools());// Reducer store

function App() {
  // States
  const [value, setValue] = useState('My context value');
  const [imageData, setImageData] = useState(imgData); 

  // Callbacks:
  const dispatch = useDispatch();

  // Saving selected value from redux store 
  const selectedValue: string|undefined = useSelector((state: RootState) => state.selectedOption);

  // 2. Saving another value from redux store
  const inputValue: string|null = useSelector((state: RootState) => state.inputTextValue);

  // Callbacks:
  const handleClick = useCallback(()=> {
    switch(selectedValue) {
      case "name":
        console.log("Selected value --> ",selectedValue);
        console.log(inputValue);
        return dispatch(setName(inputValue));
      case "surname":
        return dispatch(setSurname(inputValue));
      case "birthYear":
        return dispatch(setBirthYear(inputValue));
      case "course":
        return dispatch(setCourse(inputValue));
      case "tutor":
        return dispatch(setTutor(inputValue));
      default:
        return selectedValue;
    }
  }, [dispatch]);

  return (
    <>
      <div className="App">
        <Provider store={store}> {/* Redux store */}
          <Context.Provider value={{ value, setValue }}> {/* Esercizio card */}
            <Card />
          </Context.Provider>

          <StudentExercise 
            clickHandler={handleClick} 
            title={"changing values!"}
          />
        </Provider>
      </div>
    </>
  );
}

export default App;

我的期望是在最外层的组件中定义一个回调,在本例中是App,这样我就可以重用StudentExercise组件,但handleClick作为prop传递。

z9ju0rcb

z9ju0rcb1#

问题是这个App组件是渲染Redux Provider组件并将存储提供给***其子ReactTree的组件。这意味着App本身无法访问存储,因为在ReactTree中没有任何更高的Redux提供程序。
Provider组件在ReactTree中移到更高的位置,以便App可以访问redux存储。
示例:

import React, { useCallback, useState } from 'react';
import { useDispatch, useSelector } from "react-redux";
import './App.css';
import { Card } from './components/organism/Card';
import { Context } from './context/Context';
import { imgData } from "./context/Context";
import StudentExercise from "./components/organism/studentExercise/studentExercise";
import { optionsArray } from "./redux/reducers/SelectedOption/selectedOption";
import {
    setBirthYear,
    setCourse,
    setName,
    setSurname,
    setTutor
} from "./redux/actions";
import type { RootState } from './index.tsx';

...

function App() {
  const [value, setValue] = useState('My context value');
  const [imageData, setImageData] = useState(imgData);
   
  const dispatch = useDispatch();

  const selectedValue: string|undefined = useSelector((state: RootState) => state.selectedOption);
  const inputValue: string|null = useSelector((state: RootState) => state.inputTextValue);

  const handleClick = useCallback(()=> {
    switch(selectedValue) {
      case "name":
        return dispatch(setName(inputValue));
      case "surname":
        return dispatch(setSurname(inputValue));
      case "birthYear":
        return dispatch(setBirthYear(inputValue));
      case "course":
        return dispatch(setCourse(inputValue));
      case "tutor":
        return dispatch(setTutor(inputValue));
      default:
        return selectedValue;
    }
  }, [dispatch]);

  return (
    <div className="App">
      <Context.Provider value={{ value, setValue }}>
        <Card />
      </Context.Provider>
      <StudentExercise 
        clickHandler={handleClick} 
        title="changing values!"
      />
    </div>
  );
}

export default App;
import { Provider } from "react-redux";
import {createStore} from "redux";
import rootReducer from "./redux";
import { composeWithDevTools } from "redux-devtools-extension";

export type RootState = ReturnType<typeof store.getState>

const store = createStore(rootReducer, composeWithDevTools());

...

<Provider store={store}>
  <App />
</Provider>

相关问题