Redux - thunkMiddleware - 作为额外参数分派不起作用

Redux - thunkMiddleware - dispatch as an extra argument doesn't work

为什么没有在 fetchit() 中读取 dispatch?

我可以解决这个问题并使其以其他方式工作,例如初始化全局变量“dispatch”并在组件中 -> dispatch = useDispatch() ... 以及其他多个方式...

但我在网上发现以这种特殊方式进行操作应该可行,所以我想知道这里缺少什么...

import React from 'react';
import { createStore, applyMiddleware} from "redux";
import loggerMiddleware from "redux-logger";
import { connect } from 'react-redux'
import { useRef } from 'react';
import thunkMiddleware from "redux-thunk";


const ADD_TASK = "addTask";

const addTask = (task) => {return ({
    type: ADD_TASK,
    payload: task
})}

const reducer = (state=[], action) => {
    switch (action.type){
        case ADD_TASK:
            return [...state, ...action.payload];
        default:
            return state;
    }
}

export const store = createStore(reducer,  applyMiddleware(thunkMiddleware,loggerMiddleware));

const fetchit = (newTask="") =>(dispatch)=>{
    console.log(">>>>>>>>>>>>>>>",dispatch);  // <<<<<<<<<<<< dispatch is not read
    if (!newTask){
        fetch("/get")
        .then(response => response.json())
        .then(result => {
            dispatch(addTask(result.tasks));
        })
        .then(()=>{
            document.documentElement.scrollIntoView(false);
        })
    }
    else {
        fetch("/add", {
            credentials: "include",
            method: "POST",
            mode: "same-origin",
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json",
                //"X-CSRFToken": csrf
            },
            body: JSON.stringify(newTask),
        })
        .then(response => response.json())
        .then(result => {
            if (result.task)
                dispatch(addTask([result.task]));            
        })
        .then(()=>{
            document.documentElement.scrollIntoView(false);
        })
    }
}

const Tasks = (props) => {
    const {state} = props;
    return [state.map(task => (
        <li key={task.id} style={{color:task.done?"blue":"red"}}>
            {task.task} <section style={{color:"black"}}>{task.description}</section>
            <section style={{color:"lightgray"}}>{task.dateTime}</section>
        </li>
    ))]
}

var firstFetch = true;
const App = (props) => {
    if (firstFetch){
        firstFetch = false;
        fetchit();
    }

    const inputTask = useRef(null);
    const inputDescription = useRef(null);
    const fetchNewInput = () => {
        let bodydict = {"task": inputTask.current.value, "description": inputDescription.current.value};
        fetchit(bodydict);
        inputTask.current.value = "";
        inputDescription.current.value = "";
    }
    return <>
        <h1>Tasks</h1>
        <ol>
            <Tasks state={props.state || []}/>
        </ol>
        <div>
            <input ref={inputTask}/>
            <textarea ref={inputDescription}></textarea>
            <button onClick={fetchNewInput}>ADD</button>
        </div>
    </>
}

const mapStateToProps = (state) => {
    return {state: state};
}
const mapDispatchToProps = (dispatch) => {return {
    fetchit:(something)=> dispatch(fetchit(something)),
    addTask: (something) => dispatch(addTask(something)),
}}

export default connect(mapStateToProps, mapDispatchToProps)(App);


遗漏的步骤 --> 从 props 中提取函数
const App = ({fetchit}) => {}

本节中:

 const fetchNewInput = () => {
    let bodydict = {"task": inputTask.current.value, "description": inputDescription.current.value};
    fetchit(bodydict);
    inputTask.current.value = "";
    inputDescription.current.value = "";
}

你正在调用 thunk 本身,而你应该 dispatch fetchit。您可以通过 props.fetchit 访问调度 fetchit,正如您在 mapDispatchToProps

中定义的那样
        props.fetchit(bodydict);

我想同样的命名让你感到困惑。

此外,您可以像这样调度 addTask:

        props.addTask(task);