如何在react-redux-typescript中将store状态作为prop传递?

huangapple go评论92阅读模式
英文:

How to pass store state as a prop in react-redux-typescript?

问题

我试图将信息从存储的初始状态传递到渲染组件,但它没有显示出来。组件本身的控制台记录显示它是未定义的。初始状态没有问题,我可以使用App.tsx中的控制台记录访问它,所以我怀疑是将它作为属性传递或者需要使用componentDidMount或类似的方式进行初始化。

reducers.tsx:

import { combineReducers } from 'redux';
import {
    TaskListState,
    TaskActionTypes,
    ITask,
    ADD_TODO
} from './types';

const initialState: TaskListState = {
    tasks: [
        {
            name: "testing123",
            done: false,
        }
    ]
}

export function taskReducer(state = initialState, action: TaskActionTypes)
    : TaskListState {
        switch(action.type){
            case ADD_TODO:
                let newTask: ITask = {
                    name: action.name,
                    done: false
                }
                return {
                    tasks: [...state.tasks, newTask]
                }
            default:
                return state
        }
}

//create another reducer for the filtering, then combine the reducers

const TaskList = combineReducers({
    taskReducer
})

export default TaskList

GetTask.tsx:

import { connect } from 'react-redux';
import { TaskListState } from '../../redux/tasks/types';
import { Tasks } from '../tasks/Tasks';

const mapStateToProps = (state: TaskListState) => ({
    tasks: state.tasks
})

const mapDispatchToProps = {
}

export const Connector = connect(mapStateToProps, mapDispatchToProps)(Tasks)

Tasks.tsx:

import { ITask } from '../../redux/tasks/types';

import React from 'react';
import './Tasks.css';

type Props = {
    tasks: ITask[];
}

export const Tasks: React.FC<Props> = (props: Props) => {
    const { tasks } = props;
    console.log(tasks);
    return (
        <div>
        { tasks }
        </div>
    )
}
英文:

I'm trying to pass information from the initial state of store to a component where it's rendered, but it's not showing. A console.log in the component itself showed that it was undefined. There is nothing wrong with the initial state, I can access it using a console.log statement in App.tsx, so I suspect it's got something to do with passing it down as a prop or it needs initialization with componentDidMount or similar.

reducers.tsx:

import { combineReducers } from &#39;redux&#39;;
import {
    TaskListState,
    TaskActionTypes,
    ITask,
    ADD_TODO
} from &#39;./types&#39;

const initialState:TaskListState = {
    tasks: [
        {
            name: &quot;testing123&quot;,
            done: false,
        }
    ]
}

export function taskReducer(state = initialState, action: TaskActionTypes)
    : TaskListState {
        switch(action.type){
            case ADD_TODO:
                let newTask:ITask = {
                    name: action.name,
                    done: false
                }
                return {
                    tasks: [...state.tasks, newTask]
                }
            default:
                return state
        }
}

//create another reducer for the filtering, then combine the reducers

const TaskList = combineReducers({
    taskReducer
})

export default TaskList

GetTask.tsx:

import { connect } from &#39;react-redux&#39;
import { TaskListState } from &#39;../../redux/tasks/types&#39;
import { Tasks } from &#39;../tasks/Tasks&#39;

const mapStateToProps = (state:TaskListState) =&gt; ({
    tasks: state.tasks
})

const mapDispatchToProps = {
}

export const Connector = connect(mapStateToProps, mapDispatchToProps)(Tasks)

Tasks.tsx:

import { ITask } from &#39;../../redux/tasks/types&#39;

import React from &#39;react&#39;;
import &#39;./Tasks.css&#39;;

type Props = {
    tasks: ITask[];
}

export const Tasks: React.FC&lt;Props&gt; = (props:Props) =&gt; {
    const { tasks } = props;
    console.log(tasks);
    return (
        &lt;div&gt;
        { tasks }
        &lt;/div&gt;
    )
}

答案1

得分: 0

我刚刚简要检查了你的脚本,我认为你的 reducer 函数是错误的。

export function taskReducer(state = initialState, action: TaskActionTypes)
    : TaskListState {
        switch(action.type){
            case ADD_TODO:
                let newTask:ITask = {
                    name: action.name,
                    done: false
                }
                return {
                    // tasks: [...state.tasks, newTask]
                    [...state.tasks, newTask]
                }
            default:
                return state
        }
}

希望这对你有用。

英文:

I just breifly check your script and i think your reducer function is wrong

export function taskReducer(state = initialState, action: TaskActionTypes)
    : TaskListState {
        switch(action.type){
            case ADD_TODO:
                let newTask:ITask = {
                    name: action.name,
                    done: false
                }
                return {
                    // tasks: [...state.tasks, newTask]
                    [...state.tasks, newTask]
                }
            default:
                return state
        }
}

I hope it will works for you.

答案2

得分: 0

在下面的代码行中:

export const Connector = connect(mapStateToProps, mapDispatchToProps)(Tasks)

您正在添加Tasks组件,但没有传递一个名为tasks的prop,这就是为什么它显示为未定义。尝试在同一个文件中渲染组件,或者您可以这样做:

mapStateToProps和mapDispatchToProps都将ownProps作为第二个参数。

[mapStateToProps(state, [ownProps]): stateProps](函数):
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps](对象或函数):

供参考 这里

英文:

In the below line

export const Connector = connect(mapStateToProps, mapDispatchToProps)(Tasks)

you are adding the Tasks component but you are not passing a prop called tasks thats why it is showing as undefined try rendering the component in the same file

Or you can do it like this

mapStateToProps and mapDispatchToProps both take ownProps as the second argument.

[mapStateToProps(state, [ownProps]): stateProps] (Function):
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function):

For reference here

答案3

得分: 0

当你将taskReducer传递给combineReducers时,使用对象属性缩写,你的reducer将在存储中被命名为taskReducer,你的存储看起来像这样:

const store = {
  taskReducer: {
    tasks: [{
      name: "testing123",
      done: false,
    }]
  }
}

因此,当你尝试在mapStateToProps中选择tasks时,state.tasksundefined

根状态的类型不是TaskListState,要获取你的存储的类型,请使用ReturnType

type RootState = ReturnType<typeof TaskList>

最后,在mapStateToProps中更改到你的tasks列表的路径,与RootState的新类型一起,这将防止将来出现此类错误。

const mapStateToProps = (state: RootState) => ({
    tasks: state.taskReducer.tasks
})
英文:

When you pass the taskReducer to combineReducers using object property shorthand, your reducer will be named taskReducer in the store, your store looks like this

const store = {
  taskReducer: {
    tasks: [{
      name: &quot;testing123&quot;,
      done: false,
    }]
  }
}

So when you try to select tasks in mapStateToProps, state.tasks is undefined

The type of the root state is not TaskListState, to get the type of your store use ReturnType

type RootState = ReturnType&lt;typeof TaskList&gt;

And finally change the path to your tasks list in mapStateToProps together with the new type of the RootState which will prevent this kind of errors in the future

const mapStateToProps = (state: RootState) =&gt; ({
    tasks: state.taskReducer.tasks
})

huangapple
  • 本文由 发表于 2020年1月6日 20:25:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612106.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定