将元素添加到MongoDB后视图未更新

问题描述 投票:0回答:1

[已解决]我正在尝试使用Redux / React / Mongo / Typescript创建一个小型应用程序,但遇到一个问题,当我向数据库中添加元素时,我可以在表中看到新添加的行,但其中没有值。但是刷新页面后,值就存在了。我认为这是因为具有记录的数组会立即刷新,而新元素尚未在数据库中。我使用了await / async,但是并没有解决这个问题。有人可以帮我吗?

Action.ts

export const getAllTeams: ActionCreator<ThunkAction<Promise<any>, 
    ITeam[],                 
    null,                       
    ITeamGetAllAction          
    >> = () => {
    return async (dispatch: Dispatch) => {
        await axios.get('http://localhost:5000/teams/')
            .then(res => {
                    dispatch({
                        teams: res.data,
                        type: TeamActionsTypes.GET_ALL,
                    })
                }
            );
    };
};
export const addTeam: ActionCreator<ThunkAction<Promise<any>,
    ITeamAddTeamAction,
    ITeam,
    ITeamAddTeamAction         
    >> = (team: ITeam) => {
    return async (dispatch: Dispatch) => {
        await axios.post('http://localhost:5000/teams/add', team)
            .then(res => {
                dispatch({
                    type: TeamActionsTypes.ADD_TEAM,
                    result: res,
                });
            })
    };
};

Reducer.ts:

export const teamReducer: Reducer<ITeamState, TeamActions> = (
    state = initialTeamState,
    action,
) => {
    switch (action.type) {
        case TeamActionsTypes.GET_ALL: {
            return {
                ...state,
                teams: action.teams,
            };
        }
        case TeamActionsTypes.ADD_TEAM: {
            return{
                ...state,
                teams: [action.result,...state.teams]
            }
        }
        case TeamActionsTypes.GET_ONE: {
            return{
                ...state,
            }
        }
        default:
            return state;
    }
};

Component.tsx

interface RatingTableProps {
    getTeams: () => Promise<TeamActionsTypes.GET_ALL>;
    teams: ITeam[];
}

const RatingTable: React.FC<RatingTableProps> = ({
    getTeams,
    teams
}) => {
    useEffect(()=>{
        getTeams();
    },[]);

    return (
        <table className="striped">
            <thead>
            <tr>
                <th>Team</th>
                <th className="right-align">Clicks</th>
            </tr>
            </thead>
            <tbody>
            {teams && teams.map(team => {
                return <>
                    <tr key={team.name}>
                        <td>{team.name}</td>
                        <td className="right-align">{team.count}</td>
                    </tr>
                </>
            })}
            </tbody>
        </table>
    )
};

const mapStateToProps = (store: IAppState) => {
    return {
        teams: store.teamState.teams,
    };
};

const mapDispatchToProps = (dispatch: ThunkDispatch<any, any, AnyAction>) => {
    return {
        getTeams: () => dispatch(getAllTeams()),
    };
};

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

ComponentAdd.tsx

interface RatingFormProps{
    addTeam: (team: ITeam) => Promise<TeamActionsTypes.ADD_TEAM>;
}

const RatingForm: React.FC<RatingFormProps> = ({
    addTeam
})=> {
    const [teamName, setTeamName] = useState<string>('');

    const changeHandle = (event: React.ChangeEvent<HTMLInputElement>) => {
        setTeamName(event.target.value);
    };

    const handleSubmit = (event: React.FormEvent) =>{
        event.preventDefault();
        addTeam({
            name: teamName,
            count: 0,
        });
        setTeamName('')
    };

    return (
        <div className="row">
            <form onSubmit={handleSubmit}>
                <div className="inputField col s6">
                    <label htmlFor="teamName" className="active">
                        Name your team:
                    </label>
                    <input
                        onChange={changeHandle}
                        value={teamName}
                        type="text"
                        id="teamName"
                        placeholder="Best team name ever"
                    />
                </div>
                <div className="col s6">
                    <button className="btn-large waves-effect waves-light" type="submit" name="action">Submit
                    </button>
                </div>
            </form>
        </div>
    )

};
const mapDispatchToProps = (dispatch: ThunkDispatch<any, any, AnyAction>) => {
    return {
        addTeam: (team: ITeam) => dispatch(addTeam(team)),
    };
};

export default connect(
    null,
    mapDispatchToProps,
)(RatingForm);

teams.js(路线)

router.route('/').get(async (req, res) => {
    await Team.find()
        .then(teams => res.json(teams))
        .catch(err => res.status(400).json('Error: ' + err));
});

router.route('/add').post(async (req, res) => {
    const name = req.body.name;
    const count = 0;
    const newTeam = new Team({name, count,});
    await newTeam.save()
        .then(() => res.json('Team added to database!'))
        .catch(err => res.status(400).json('Error: ' + err));

});

[在用户界面中的外观:before adding new elementafter adding new element

如果您需要任何其他信息或代码,请告诉我。谢谢!

更新1:感谢评论,当然一个大错误是在发布后返回实际对象,而不是字符串(对我感到羞耻)

router.route('/add').post(async (req, res) => {
    const name = req.body.name;
    const count = 0;
    const newTeam = new Team({name, count,});
    await newTeam.save()
        .then((team) => res.json(team))
        .catch(err => res.status(400).json('Error: ' + err));

});

更新2:天哪,这是一个愚蠢的错误先前的更新解决了一个问题,但是在我从dipatch接收到未定义的值之后,这是因为我返回的是Promis,但没有返回值。

export const addTeam: ActionCreator<ThunkAction<Promise<any>,
    ITeamAddTeamAction,
    ITeam,
    ITeamAddTeamAction         
    >> = (team: ITeam) => {
    return async (dispatch: Dispatch) => {
        await axios.post('http://localhost:5000/teams/add', team)
            .then(res => {
                dispatch({
                    type: TeamActionsTypes.ADD_TEAM,
                    result: res.data, //<- Instead of just res
                });
            })
    };
};

感谢所有花了一些时间的人,一如既往的愚蠢错误。

reactjs mongodb typescript mongoose redux
1个回答
0
投票

您应该从后端API返回更新后的team。您可以像这样修改您的API。

router.route('/add').post(async (req, res) => {
    const name = req.body.name;
    const count = 0;
    const newTeam = new Team({name, count,});
    await newTeam.save()
        .then(team => res.json(team))
        .catch(err => res.status(400).json('Error: ' + err));

});

如果问题仍然存在,请删除评论。

© www.soinside.com 2019 - 2024. All rights reserved.