Redux-Toolkit-如何将状态传递给子组件

时间:2020-11-06 09:22:43

标签: typescript redux react-redux

我使用redux将数据存储在应用程序中。我想知道该方法,如何将数据从状态传递到子组件。我知道,在useContext的情况下,我创建了Provider并可以通过以下简单方式提取数据:

const myData = React.useContext(MyContext);

但是我不知道如何有效地在redux中做同样的事情。我知道mapeStateToProps,但我希望有更简单的方法。 看我的代码:

import React from 'react';

import { useDispatch, useSelector } from 'react-redux';
import { RootState, store } from 'redux/store';
import { IStep, changeValue } from 'redux/reducers/multiStepForm';   

import Stepper from './Stepper';
import Step from './Step';
import Controls from './Controls';

const MultiStepForm = (): JSX.Element => {
  const activeStep = useSelector((state: RootState) => state.multiStepForm.activeStep);
  const steps = useSelector((state: RootState) => state.multiStepForm.steps);
  const dispatch = useDispatch();

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    dispatch(changeValue(e.target.value));
  };

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    console.log(
      'Form values',
      steps.map((step: IStep) => step.value)
    );
  };

  return (
    <div style={{ margin: '0 200px' }}>
      <h2>MultiStep Form</h2>
      <Stepper activeStep={activeStep} steps={steps} />
      <form onSubmit={handleSubmit}>
        <Step activeStep={activeStep} steps={steps} handleChange={handleChange} />
        <Controls activeStep={activeStep} steps={steps} />
      </form>
    </div>
  );
};

export default MultiStepForm;

因此,如您所见,我将道具从状态传递给孩子(步进,步进,控件)。他们每个人都使用相同的道具(activeStep和steps)。

如何使其更容易/更智能?

让我们以其中一个孩子为例:

import React from 'react';
import { IStep, InitialMultiStepFormState } from 'redux/reducers/multiStepForm';
import { StepperLine, StepperNumber, StepperStep, StepperWrapper } from './Stepper.styled';

const Stepper = ({ activeStep, steps }: InitialMultiStepFormState): JSX.Element => {
  const stepNumber = (step: number) => step + 1;

  return (
    <StepperWrapper>
      {steps.map((step: IStep) => (
        <StepperStep key={step.id + 1}>
          <StepperNumber completed={step.id <= activeStep}>{stepNumber(step.id)}</StepperNumber>
          {stepNumber(step.id) === steps.length ? null : (
            <StepperLine completed={stepNumber(step.id) <= activeStep} />
          )}
        </StepperStep>
      ))}
    </StepperWrapper>
  );
};

export default Stepper;

请提供任何建议或带有说明的链接。

1 个答案:

答案 0 :(得分:1)

React的目的是将道具传递给直接子组件。这无可避免,这是组件和道具的用途。

如果您必须传递多个(> 2-5)级别的内容,则可以在以后的这些组件中进行相同的useSelector调用(将它们包装到自定义钩子中!),而在它们之间不进行任何传递,但是对于直系子女,这是必经之路。

即使为此使用上下文,也可能会被视为反模式。在解决诸如上下文之类的问题之前,您应该已经尝试过道具和合成,因为上下文也不是免费提供的。