简体   繁体   English

使用输入更改 Redux 存储

[英]Changing Redux store using input

I'm really new to React, Typescript and Redux, < a week using them.我对 React、Typescript 和 Redux真的很陌生,< 使用它们一周。

What I need, is to store a "userName" on Redux's storage, in order to validate it against other values in the storage.我需要的是在 Redux 的存储中存储一个“用户名”,以便根据存储中的其他值对其进行验证。 My problem specifically is not being able to store the userName, mostly because all examples use class based components, while I'm using functional ones.我的问题特别是无法存储用户名,主要是因为所有示例都使用基于类的组件,而我使用的是功能组件。 Here's what I have as of now:这是我目前所拥有的:

 //User input component import React, { useState } from "react"; import { connect } from "react-redux"; import { bindActionCreators } from "redux"; import * as actions from "../../actions"; import Button from "@material-ui/core/Button"; import TextField from "@material-ui/core/TextField"; import Dialog from "@material-ui/core/Dialog"; import DialogActions from "@material-ui/core/DialogActions"; import DialogContent from "@material-ui/core/DialogContent"; import DialogContentText from "@material-ui/core/DialogContentText"; import DialogTitle from "@material-ui/core/DialogTitle"; import { ApplicationStateInterface } from "../../combineReducers"; import { Box } from "@material-ui/core"; interface channelCreatorInterface { open: boolean; hideChannelCreator?: any; handleFormChange?: any; } const mapStateToProps = ( state: ApplicationStateInterface, ownProps: channelCreatorInterface ) => { return { ...ownProps, }; }; const mapDispatchToProps = (dispatch: any) => ({ hideChannelCreator() { dispatch(actions.hideChannelCreator()); }, }); const ChannelCreator = (props: channelCreatorInterface) => { return ( <div> <Dialog open={props.open} onClose={props.hideChannelCreator} aria-labelledby='form-dialog-title'> <DialogTitle id='form-dialog-title'>Create channel name</DialogTitle> <DialogContent> <DialogContentText> To create a channel name, please enter your desired name here. We will check for availability. </DialogContentText> <TextField autoFocus margin='dense' id='name' label='Channel name' type='username' fullWidth onChange= {HERE IS THE EVENT I NEED TO CAPTURE} /> </DialogContent> <DialogActions> <Button color='primary' onClick={props.hideChannelCreator}> Cancel </Button> <Box id='saveButton'> <Button variant='contained' color='primary'> Save </Button> </Box> </DialogActions> </Dialog> </div> ); }; export default connect(mapStateToProps, mapDispatchToProps)(ChannelCreator);


 //Form change action import { makeActionCreator } from "../utility"; export const HANDLE_FORM_CHANGE = "HANDLE_FORM_CHANGE"; export const handleFormChange = makeActionCreator( HANDLE_FORM_CHANGE, "payload" );


 //Reducer import { constants } from "os"; import { Reducer } from "redux"; import { CREATE_CHANNEL, DISPLAY_CHANNEL_CREATOR, HIDE_CHANNEL_CREATOR, HANDLE_FORM_CHANGE, } from "../actions"; export interface channelCreatorInterface { open: boolean; state: "idle" | "saving" | "correctly saved"; channelName: ""; } export const channelCreatorInitialState: channelCreatorInterface = { open: false, state: "idle", channelName: "", }; export const channelCreatorReducer: Reducer<any, any> = ( channelCreatorState: channelCreatorInterface = channelCreatorInitialState, action: { type: any; state: channelCreatorInterface } ) => { switch (action.type) { case CREATE_CHANNEL: return { ...channelCreatorState, state: "saving", }; case DISPLAY_CHANNEL_CREATOR: return { ...channelCreatorState, open: true, }; case HIDE_CHANNEL_CREATOR: return { ...channelCreatorState, open: false, }; case HANDLE_FORM_CHANGE: return { ...channelCreatorState, channelName: "", }; default: return channelCreatorState; } };


First, let's go to your question:首先,让我们回到你的问题:

Your reducer would need to use a payload from your action:您的减速器需要使用您的操作中的有效载荷:


        case HANDLE_FORM_CHANGE:
            return {
                ...channelCreatorState,
                channelName: action.payload,
            };

and in your component, you would then use an event handler to dispatch an action with that payload:然后在您的组件中,您将使用事件处理程序来分派具有该负载的操作:

const mapDispatchToProps = (dispatch: any) => ({
    // ...
    setChannelName: (channelName: string) => dispatch({ type: HANDLE_FORM_CHANGE, payload: channelName })
});
// in your component:
                    <TextField
                        autoFocus
                        margin='dense'
                        id='name'
                        label='Channel name'
                        type='username'
                        fullWidth
            onChange={event => props.setChannelName(event.target.value)}
                    />

But please note, that this is a very outdated style of writing redux.但请注意,这是一种非常过时的 redux 编写风格。 For one, we recommend using the react-redux hooks useSelector and useDispatch , which can replace connect in function components.一方面,我们推荐使用 react-redux 钩子useSelectoruseDispatch ,它们可以替代函数组件中的connect Also, we recommend using redux toolkit instead of writing plain redux reducers by hand, as that will save you a lot of code and also help a lot with the typescript typings.此外,我们建议使用redux 工具包而不是手动编写普通的 redux reducers,因为这将为您节省大量代码,并且对打字稿类型也有很大帮助。

If you are looking for an up-to-date tutorial, the official Essentials Tutorial is the best place to start.如果您正在寻找最新的教程,官方Essentials 教程是最好的起点。

Also, if you have any quick questions that don't make good material for a stackoverflow questions, be sure to visit us over in the official redux channel on the reactiflux discord server.此外,如果您有任何不能作为 stackoverflow 问题的好材料的快速问题,请务必在 reactiflux discord 服务器上的官方 redux 频道中访问我们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM