首页 > 解决方案 > Redux 商店未更新

问题描述

我需要显示一个嵌套数组。但是我无法显示嵌套列表,因为我的 redux 商店没有更新。下面是数据结构的示例:

{
email: "fgh@gmail.com"
tId: 2
teacherClasses: null
teacherUserRef: 3
user:
{
admin: null
firstName: "fgh"
id: 3
lastName: "fgh"

}}

我无法显示用户内部的任何内容。

下面是代码:

减速器:

import { ACTION_TYPES } from "../actions/teacher";
const initialState = {
    list: []
   
}


export const teacher = (state = initialState, action) => {

    switch (action.type) {
        case ACTION_TYPES.FETCH_ALL:
            
            return {
                ...state,
                list: [
                    ...action.payload]
            }
        case ACTION_TYPES.FETCHBYID:
            return {
                ...state,
                list: [action.payload]
            }

        case ACTION_TYPES.CREATE:
            return {
                ...state,
                list: [...state.list, action.payload]
            }

        case ACTION_TYPES.UPDATE:
            return {
                ...state,
                list: state.list.map(x => x.id == action.payload.id ? action.payload : x)
            }

        case ACTION_TYPES.DELETE:
            return {
                ...state,
                list: state.list.filter(x => x.id != action.payload)
            }

        default:
            return state
    }
}

组件页面:

老师.js:


const Teacher = ({ ...props }) => {
    const [currentId, setCurrentId] = useState(0)

    useEffect(() => {
        console.log("teacher call")
        
        props.fetchAllTeacher()
        console.log(props.teacherList)
    }, [currentId])//componentDidMount

    return (
        <div className="site-layout-background" style={{ padding: 24, textAlign: 'center' }}>
        <Space direction="vertical" align="center">
                
                        <TableContainer>
                            <Table>
                                <TableHead >
                                    <TableRow>
                                        <TableCell>Name</TableCell>
                                        <TableCell>Email</TableCell>

                                        <TableCell></TableCell>
                                    </TableRow>

                                    {
                                        
                                         props.teacherList.map((record, index) => {
                                        return (<TableRow key={index} hover>
                                            <TableCell>{record.email}</TableCell>
                                            <TableCell>{record.user.firstName}</TableCell>
                                            <TableCell>
                                                <ButtonGroup variant="text">
                                                    <Button icon={<DeleteOutlined />} onClick={() => onDelete(record.user.id)}></Button>
                                                </ButtonGroup>
                                            </TableCell>
                                            

                                        </TableRow>)
                                    })}
                                </TableHead>
                                <TableBody>
                                    
                                </TableBody>
                            </Table>
                        </TableContainer>

            </Space>
            </div>
            
        
    );
}

const mapStateToProps = state => ({
    teacherList: state.teacher.list,
    userList: state.user.list
})

const mapActionToProps = {
    fetchAllTeacher: actions.fetchAll,
    deleteUser: actions1.Delete
}

export default connect(mapStateToProps, mapActionToProps)(Teacher);

动作创建者:

import api from "./api";

export const ACTION_TYPES = {
    CREATE: 'CREATE',
    UPDATE: 'UPDATE',
    DELETE: 'DELETE',
    FETCH_ALL: 'FETCH_ALL',
    FETCHBYID: 'FETCHBYID'
}



export const fetchAll = () => dispatch => {
    api.teacher().fetchAll()
        .then(response => {
            dispatch({
                type: ACTION_TYPES.FETCH_ALL,
                payload: response.data
            })
        })
        .catch(err => console.log(err))
}
export const fetchById = (id) => dispatch => {
    api.teacher().fetchById(id)
        .then(response => {
            dispatch({
                type: ACTION_TYPES.FETCHBYID,
                payload: response.data
            })
        })
        .catch(err => console.log(err))
}

export const create = (data, onSuccess) => dispatch => {

    api.teacher().create(data)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.CREATE,
                payload: res.data
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

export const update = (id, data, onSuccess) => dispatch => {

    api.teacher().update(id, data)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.UPDATE,
                payload: { id, ...data }
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

export const Delete = (id, onSuccess) => dispatch => {
    api.teacher().delete(id)
        .then(res => {
            dispatch({
                type: ACTION_TYPES.DELETE,
                payload: id
            })
            onSuccess()
        })
        .catch(err => console.log(err))
}

我收到一条错误消息,说 firstName 未定义。

请帮忙。

标签: reactjsreact-redux

解决方案


您的 redux 存储没有更新的原因是您必须调度操作。正确的签名mapDispatchToProps是:

const mapDispatchToProps = (dispatch) => {
    fetchAllTeacher: () => dispatch(actions.fetchAll()),
    deleteUser: (id) => dispatch(actions.Delete(id)),
}

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

但是有更好的方法。你实际上是在混合两种范式,虽然上面的方法可以工作,但你应该使用 redux 钩子,因为你已经创建了一个功能组件并且你已经在使用useEffect钩子了。

它可以像这样工作:

import { useSelector, useDispatch } from "react-redux"

const Teacher = ({ ...props }) => {
    const dispatch = useDispatch();
    useEffect(() => {
        console.log("teacher call")
        
        const teachers = props.fetchAllTeacher();
        // dispatch the action that will add the list to the redux state
        dispatch(actions.fetchAll(teachers));
    }, [currentId]);
    
    // fetch the teacher list from redux store

    const teacherList = useSelector(state => state.teacher.list);
    return (...);
}

考虑将选择器定义移动state => state.teacher.list到它自己的模块中,以便您可以在其他组件中重用它,并在商店结构发生变化时在一处更新它。

看起来您的代码中没有调度任何操作,因此问题不是由于数据嵌套造成的。您可以毫无问题地在您的州拥有嵌套数据。


推荐阅读