Redux 访问另一个组件中的状态

时间:2021-05-18 05:35:58

标签: redux react-redux state action reducers

我无法访问组件中的状态。我有一个组件(添加页面),用户可以在其中添加“名称”和“重量”。我想要发生的是当用户单击提交时添加的“名称”和“重量”显示在另一个组件(主页)上。当我在主页中控制台记录状态时,我得到未定义。我的 DevTools 显示状态正在使用添加的名称和权重进行更新,但我不知道如何访问它。 以下是我的操作:

export const getMovements = (name) => {
    return {
        type: constants.GET_MOVEMENTS,
        name,
    }
};

export const addMovement = (name, weight) => {
    history.push('/')
    return {
        type: constants.ADD_MOVEMENT,
        name, 
        weight,
    }
};

这是我的减速器:

const initialState = {
    name: [],
    weight: [],
};

const addMovementReducer = (state = initialState , action) => {
    switch (action.type) {
        case ADD_MOVEMENT:
            return { ...state, name: action.name, weight: action.weight }
        default:
            return state;
    }
};

const getMovementsReducer = (state = {}, action) => {
    switch (action.type) {
        case GET_MOVEMENTS:
            return { ...state, name: action.name, weight: action.weight }
        default:
            return state;
    }
};

这是我的添加页面组件:

const AddPage = () => {
    const [name, setName] = useState('');
    const [weight, setWeight] = useState(0);
    const classes = useStyles();
    const dispatch = useDispatch();

    console.log(name, weight);

    return (
        <div>
            <Header title="Add Page" />
            <div className={classes.addPage}>
                <div className={classes.addMovementDiv}>
                    <TextField 
                        className={classes.movementName} 
                        key="name" 
                        label="Enter Movement Name" 
                        InputProps= {{className: "textBoxColor"}}
                        variant="outlined"
                        onChange={event => {
                            const { value } = event.target;
                            setName(value);
                        }} 
                         />    
                    <TextField 
                        className={classes.movementWeight} 
                        key="weight" 
                        label="Enter Movement Weight" 
                        type="number" 
                        variant="outlined"
                        onChange={event => {
                            const { value } = event.target;
                            setWeight(value);
                        }}
                        InputProps= {{endAdornment: <InputAdornment position="end">lb</InputAdornment>, className: "textBoxColor"}} />
                    <Button 
                        className={classes.addButton}
                        variant="outlined"
                        onClick={() => dispatch(addMovement(name, weight))}
                        >
                        <AddCircleIcon />
                    </Button>
                </div>
            </div>
        </div>
    );
};

const mapStateToProps = (state) => {
    return {
        name: state.name,
        weight: state.weight,   
    }   
};

const mapDispatchToProps = (dispatch) => {
    return({
        addMovement: (name, weight) => dispatch(addMovement(name, weight))
    })
};

const withConnect = connect(
    mapStateToProps,
    mapDispatchToProps,
);

export default compose(withConnect)(AddPage);

这是我的主页组件:

const HomePage = (props) => {
    const classes = useStyles();
    const newMovements = props.name;

    return (
        <div>
            <Header title={"Home Page" }/>
            {newMovements}
            <div className={classes.fabDiv}>
                <Fab 
                    className={classes.fab}
                    onClick={() => history.push(`/add`)}>  
                    <AddIcon />      
                </Fab>
            </div>
        </div>
    );
};

const mapStateToProps = (state) => {
    return {
        name: state.name
    }  
};

const mapDispatchToProps = (dispatch) => {
    return({
        getMovements: (name) => dispatch(getMovements(name))
    })
};

const withConnect = connect(
    mapStateToProps,
    mapDispatchToProps,
);

export default compose(withConnect)(HomePage);

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

代替

    const [name, setName] = useState('');
    const [weight, setWeight] = useState(0);

这是非 Redux、组件本地状态,您必须使用连接的 props.nameprops.weight

由于您使用的是函数组件和钩子,您还可以使用 react-redux hooks useSelectoruseDispatch,这比使用 connect 容易得多。

所以跳过所有的 connectmapStateToPropsprops.name 直接做

  const name = useSelector(state => state.name)
  const weight = useSelector(state => state.weight)

答案 1 :(得分:0)

仅添加 phry 的精彩答案,像“mapStateToProps”这样的方法类似于“with”方法(“withStyles”、“withRouter”等)。当我们使用基于类的组件时最常用。有了钩子,这个约定就不再那么常见了,关于 redux,正如 phry 所说,useSelector 钩子正是你所需要的。我确实相信这有一个小例外……(虽然这是一种意见/个人偏好),如果状态/逻辑是异步的,我宁愿不做 useSelector。我个人倾向于只使用带有同步操作的 useSelector。