IT이야기

Redux 사용

cyworld 2021. 10. 7. 21:04
반응형

저는 Redux를 사용하고 있습니다. Redux 저장소에서 제어된 입력 상태를 관리해야 하나요 아니면 구성 요소 수준에서 setState를 사용해야 하나요?


나는 반응 양식을 관리하는 가장 좋은 방법을 알아 내려고 노력해 왔습니다. onChange를 사용하여 작업을 실행하고 양식 데이터로 내 redux 저장소를 업데이트하려고 했습니다. 나는 또한 로컬 상태를 생성하려고 시도했으며 내 양식이 제출되면 redux 저장소를 트리거 및 작업하고 업데이트합니다.

제어된 입력 상태를 어떻게 관리해야 합니까?


  1. 구성 요소의 자체 상태를 사용할 수 있습니다. 그런 다음 그 상태를 취하여 조치에 대한 인수로 제공합니다. 이것은 React Docs 에 설명된 대로 거의 "React way" 입니다.

  2. Redux Form 도 확인할 수 있습니다 . 기본적으로 설명된 작업을 수행하고 양식 입력을 Redux State와 연결합니다.

첫 번째 방법은 기본적으로 최대 제어 및 최대 상용구와 같은 모든 작업을 수동으로 수행한다는 것을 의미합니다. 두 번째 방법은 상위 구성 요소가 모든 작업을 수행하도록 하는 것을 의미합니다. 그리고 그 사이에 모든 것이 있습니다. 양식 관리의 특정 측면을 단순화하는 여러 패키지가 있습니다.

  1. React Forms - 양식 렌더링 및 유효성 검사를 더 간단하게 만들기 위해 많은 도우미 구성 요소를 제공합니다.

  2. React JSON 스키마 - JSON 스키마 에서 HTML 양식을 작성할 수 있습니다.

  3. Formsy React - 설명에 따르면 "React JS에 대한 이 확장은 유연성과 재사용성 사이의 "스위트 스폿"을 목표로 합니다."

업데이트: 요즘 Redux Form이 다음으로 대체되는 것 같습니다.

  1. 반응 최종 양식

체크아웃할 가치가 있는 이 분야에서 또 하나의 중요한 경쟁자는 다음과 같습니다.

  1. 포믹

Redux 공동 작성자 중 한 명이 작성한 답변이 마음에 듭니다. https://github.com/reactjs/redux/issues/1287

전 세계적으로 앱에 중요하지 않고 복잡한 방식으로 변경되지 않는 임시 상태에 대해 React를 사용합니다. 예를 들어 일부 UI 요소의 토글, 양식 입력 상태입니다. 전역적으로 중요하거나 복잡한 방식으로 변경되는 상태에 Redux를 사용하세요. 예를 들어, 캐시된 사용자 또는 게시물 초안입니다.

때로는 Redux 상태에서 React 상태로(Redux에 무언가를 저장하는 것이 어색할 때) 또는 그 반대로(더 많은 구성 요소가 로컬이었던 일부 상태에 액세스해야 하는 경우) 다른 상태로 이동하고 싶을 것입니다.

경험 법칙은 덜 어색한 일을 하는 것입니다.

즉, 양식이 전역 상태에 영향을 미치지 않거나 구성 요소가 마운트 해제된 후에도 유지되어야 하는 경우 반응 상태를 유지하십시오.


TL;DR

앱에 적합하다고 생각되는 모든 것을 사용하는 것이 좋습니다(출처: Redux 문서 )


어떤 종류의 데이터를 Redux에 넣어야 하는지 결정하기 위한 몇 가지 일반적인 경험 법칙:

  • 애플리케이션의 다른 부분에서 이 데이터를 처리합니까?
  • 이 원본 데이터를 기반으로 추가 파생 데이터를 생성할 수 있어야 합니까?
  • 여러 구성 요소를 구동하는 데 동일한 데이터가 사용되고 있습니까?
  • 이 상태를 주어진 시점으로 복원할 수 있다는 것이 당신에게 가치가 있습니까(즉, 시간 여행 디버깅)?
  • 데이터를 캐시하시겠습니까(즉, 데이터가 이미 있는 경우 다시 요청하는 대신 상태를 사용)?

이러한 질문은 앱에 더 적합한 접근 방식을 쉽게 식별하는 데 도움이 될 수 있습니다. 다음은 내 앱(양식용)에서 사용하는 내 견해와 접근 방식입니다.

지역 주

  • 내 양식이 UI의 다른 구성 요소와 관련이 없을 때 유용합니다. input(들) 에서 데이터를 캡처 하고 제출하기만 하면 됩니다. 나는 이것을 간단한 양식에 가장 많이 사용합니다.
  • 내 양식의 입력 흐름을 디버깅하는 시간 여행에서 많은 사용 사례를 볼 수 없습니다(일부 다른 UI 구성 요소가 이에 종속되지 않는 한).

리덕스 상태

  • 양식이 내 앱의 다른 UI 구성 요소를 업데이트해야 할 때 유용합니다( 양방향 바인딩 과 유사 ).
  • 내 양식으로 input인해 render사용자가 입력하는 내용 따라 다른 구성 요소가 발생할 때 이것을 사용합니다 .

개인적으로 모든 것을 Redux 상태로 유지하고 로컬 구성 요소 상태에서 벗어나는 것이 좋습니다. 이는 본질적으로 ui를 상태의 함수로 보기 시작하면 완전한 브라우저 없는 테스트를 수행할 수 있고 전체 상태 기록(예: 입력 내용, 열린 대화 상자 등)에 대한 참조를 유지할 수 있기 때문입니다. , 버그가 발생했을 때 - 처음부터 상태가 아님) 디버깅 목적으로 사용자를 위해. 클로저의 영역에서 관련 트윗

추가하기 위해 편집됨: 이것은 우리와 자매 회사가 프로덕션 애플리케이션과 redux/state/ui를 처리하는 방법 측면에서 이동하는 곳입니다.


도우미 라이브러리를 사용하면 더 빠르고 모든 상용구를 피할 수 있습니다. 최적화되고 기능이 풍부할 수 있습니다. 그들이 모든 다른 측면을 더 쉽게 만들기 때문입니다. 그것들을 테스트하고 서로 다른 요구 사항에 무엇이 유용하고 더 나은지 아는 것으로 무기고를 만드는 것은 할 일입니다.

그러나 이미 모든 것을 직접 구현했다면 . 가고있는 제어 방법 . 그리고 이유 때문에 redux 가 필요합니다 . 내 프로젝트 중 하나에서. 양식 상태를 유지해야 했습니다. 따라서 다른 페이지로 이동하여 다시 오면 동일한 상태로 유지됩니다. 여러 구성 요소에 변경 사항을 전달하는 수단인 경우에만 redux가 필요합니다. 또는 상태를 저장하는 수단인 경우 복원해야 합니다.

상태가 전역이어야 하는 경우 redux가 필요합니다. 그렇지 않으면 필요하지 않습니다. 그 문제 에 대해 심층 분석을 위해 여기 에서 이 훌륭한 기사를 확인할 수 있습니다 .

겪을있는 문제 중 하나 ! 제어된 입력을 사용할 때. 모든 키 입력에서 변경 사항을 전달할 수 있다는 것 입니다. 그리고 당신 의 양식 은 얼어 붙기 시작할 것입 니다 . 달팽이가 되었습니다.

모든 변경에서 redux 플럭스를 직접 발송하고 사용해서는 안됩니다. 당신이 할 수 있는 것은 입력 상태를 컴포넌트 로컬 상태에 저장하는 것입니다. 를 사용하여 업데이트 setState()합니다. 상태가 변경되면 지연 타이머를 설정합니다. 모든 키 입력에서 취소됩니다. 마지막 키 입력은 지정된 지연 후에 디스패치 작업이 뒤따릅니다. (좋은 지연은 500ms일 수 있습니다).

( setState기본적으로 여러 개의 연속적인 키 입력을 효과적으로 처리 한다는 것을 알아두십시오 . 그렇지 않으면 위에서 언급한 것과 동일한 기술을 사용했을 것입니다(바닐라 js에서 하는 것처럼) [하지만 여기서는 setState]에 의존할 것입니다 )

다음은 예시입니다.

onInputsChange(change, evt) {
    const { onInputsChange, roomId } = this.props;

    this.setState({
        ...this.state,
        inputs: {
            ...this.state.inputs,
            ...change
        }
    }, () => {
        // here how you implement the delay timer
        clearTimeout(this.onInputsChangeTimeoutHandler); // we clear at ever keystroke
              // this handler is declared in the constructor
        this.onInputsChangeTimeoutHandler = setTimeout(() => {
           // this will be executed only after the last keystroke (following the delay)
            if (typeof onInputsChange === "function")
                    onInputsChange(this.state.inputs, roomId, evt);
        }, 500);
    })
}

다음과 같이 props를 사용하여 구성 요소를 초기화하기 위해 안티 패턴을 사용할 수 있습니다.

constructor(props) {
    super(props);

    const {
        name,
        description
    } = this.props;

    this.state = {
        inputs: {
            name,
            description
        }
    }

생성자 또는 다음 componentDidMount과 같은 후크 에서 :

componentDidMount () {
    const {
        name, 
        description
    } = this.props;

    this.setState({
        ...this.state,
        inputs: {
            name,
            description
        }
    });
}

나중에 모든 구성 요소를 장착할 때 저장소에서 상태를 복원할 수 있습니다.

또한 부모 구성 요소에서 양식을 변경해야 하는 경우 해당 부모에 함수를 노출할 수 있습니다. 바인딩된setInputs() 메서드를 설정합니다 . 그리고 구성에서 props(즉, getter 메서드)를 실행합니다 . (유용한 경우는 일부 조건 또는 상태에서 양식을 재설정하려는 경우입니다).getSetInputs()

constructor(props) {
    super(props);
    const {
         getSetInputs
    } = this.props;

   // .....
   if (typeof getSetInputs === 'function') getSetInputs(this.setInputs);
}

위에서 내가 한 일을 더 잘 이해하기 위해 입력을 업데이트하는 방법은 다음과 같습니다.

// inputs change handlers
onNameChange(evt) {
    const { value } = evt.target;

    this.onInputsChange(
        {
            name: value
        },
        evt
    );
}

onDescriptionChange(evt) {
    const { value } = evt.target;

    this.onInputsChange(
        {
            description: value
        },
        evt
    );
}

/**
 * change = {
 *      name: value
 * }
 */
onInputsChange(change, evt) {
    const { onInputsChange, roomId } = this.props;

    this.setState({
        ...this.state,
        inputs: {
            ...this.state.inputs,
            ...change
        }
    }, () => {
        clearTimeout(this.onInputsChangeTimeoutHandler);
        this.onInputsChangeTimeoutHandler = setTimeout(() => {
            if (typeof onInputsChange === "function")
                onInputsChange(change, roomId, evt);
        }, 500);
    })
}

여기 내 양식이 있습니다.

 const {
        name='',
        description=''
 } = this.state.inputs;

// ....

<Form className="form">
    <Row form>
        <Col md={6}>
            <FormGroup>
                <Label>{t("Name")}</Label>
                <Input
                    type="text"
                    value={name}
                    disabled={state === "view"}
                    onChange={this.onNameChange}
                />
                {state !== "view" && (
                    <Fragment>
                        <FormFeedback
                            invalid={
                                errors.name
                                    ? "true"
                                    : "false"
                            }
                        >
                            {errors.name !== true
                                ? errors.name
                                : t(
                                        "You need to enter a no existing name"
                                    )}
                        </FormFeedback>
                        <FormText>
                            {t(
                                "Enter a unique name"
                            )}
                        </FormText>
                    </Fragment>
                )}
            </FormGroup>
        </Col>
        {/* <Col md={6}>
            <div className="image">Image go here (one day)</div>
        </Col> */}
    </Row>

    <FormGroup>
        <Label>{t("Description")}</Label>
        <Input
            type="textarea"
            value={description}
            disabled={state === "view"}
            onChange={this.onDescriptionChange}
        />
        {state !== "view" && (
            <FormFeedback
                invalid={
                    errors.description
                        ? "true"
                        : "false"
                }
            >
                {errors.description}
            </FormFeedback>
        )}
    </FormGroup>
</Form>

ReferenceURL : https://stackoverflow.com/questions/34952530/i-am-using-redux-should-i-manage-controlled-input-state-in-the-redux-store-or-u

반응형