[reactjs] React.js 양식 구성 요소에서 상태 또는 참조를 사용합니까?

React.js로 시작하고 간단한 양식을 작성하고 싶지만 문서에서 두 가지 방법을 찾았습니다.

번째Refs를 사용하는 입니다 .

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    // TODO: send request to the server
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
    return;
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

그리고 두 번째는 사용 상태 (가) 성분 반작용 내부 :

var TodoTextInput = React.createClass({
  getInitialState: function() {
    return {
      value: this.props.value || ''
    };
  },

  render: function() /*object*/ {
    return (
      <input className={this.props.className}
      id={this.props.id}
      placeholder={this.props.placeholder}
      onBlur={this._save}
      value={this.state.value}
      />
    );
  },

  _save: function() {
    this.props.onSave(this.state.value);
    this.setState({value: ''
  });
});

두 가지 대안이 있다면 장단점을 볼 수 없습니다. 감사.



답변

짧은 버전 : refs를 피하십시오.


유지 관리에 좋지 않으며 WYSIWYG 모델 렌더링이 제공하는 단순성을 많이 잃습니다.

양식이 있습니다. 양식을 재설정하는 단추를 추가해야합니다.

  • 심판 :
    • DOM 조작
    • render는 3 분 전에 양식이 어떻게 보 였는지 설명합니다.
  • 상태
    • setState
    • render는 양식이 어떻게 보이는지 설명합니다.

입력에 CCV 번호 필드가 있고 응용 프로그램에 숫자 인 다른 필드가 있습니다. 이제 사용자는 숫자 만 입력하도록 강제해야합니다.

  • 심판 :
    • onChange 핸들러를 추가합니다 (우리는 이것을 피하기 위해 refs를 사용하지 않습니까?).
    • 숫자가 아닌 경우 onChange에서 dom 조작
  • 상태
    • 이미 onChange 핸들러가 있습니다.
    • if 문을 추가하고, 유효하지 않으면 아무 작업도하지 않습니다.
    • render는 다른 결과를 생성 할 때만 호출됩니다.

어, 신경 쓰지 마세요, PM은 그것이 유효하지 않다면 우리가 빨간 상자 그림자를하기를 원합니다.

  • 심판 :
    • onChange 핸들러가 forceUpdate 또는 무언가를 호출하도록 만드시겠습니까?
    • 렌더 출력을 기반으로 … 응?
    • 렌더링에서 유효성을 검사 할 값은 어디에서 얻습니까?
    • 요소의 className dom 속성을 수동으로 조작 하시겠습니까?
    • 나는 길을 잃었다
    • 심판없이 다시 작성 하시겠습니까?
    • 우리가 마운트 된 경우 렌더링의 dom에서 읽지 않으면 유효하다고 가정합니까?
  • 상태:
    • if 문 제거
    • this.state를 기반으로 렌더링 유효성을 검사하십시오.

우리는 부모에게 통제권을 돌려줘야합니다. 데이터는 이제 소품에 있으며 변경 사항에 대응해야합니다.

  • 심판 :
    • componentDidMount, componentWillUpdate 및 componentDidUpdate 구현
    • 이전 소품을 수동으로 비교
    • 최소한의 변경으로 dom 조작
    • 야! 우리는 react in react를 구현하고 있습니다.
    • 더 있지만 손가락이 아파
  • 상태:
    • sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js

사람들은 심판이 상태를 유지하는 것보다 ‘더 쉽다’고 생각합니다. 이것은 처음 20 분 동안은 사실 일 수 있지만 그 이후의 경험으로는 사실이 아닙니다. “물론, 몇 가지 구성 요소 만 다시 작성하겠습니다.”가 아니라 “예, 5 분 안에 완료하겠습니다”라고 말할 수있는 자세를 취하십시오.


답변

나는 몇몇 사람들이 위의 대답을 “절대 심판을 사용하지 않는”이유로 인용하는 것을 보았고 나는 나의 (그리고 내가 이야기 한 몇몇 다른 React 개발자들에게도) 의견을주고 싶다.

구성 요소 인스턴스에 대해 사용하는 것에 대해 말할 때 “참조를 사용하지 마십시오”라는 정서는 정확합니다. 즉, 컴포넌트 인스턴스를 가져오고 이에 대한 메서드를 호출하는 방법으로 ref를 사용해서는 안됩니다. 이것은 refs를 사용하는 잘못된 방법이며 refs가 빠르게 남쪽으로 이동하는 경우입니다.

참조를 사용하는 올바른 (매우 유용한) 방법은 참조를 사용하여 DOM에서 값을 가져올 때입니다. 예를 들어 해당 입력에 참조를 첨부하는 입력 필드가있는 경우 나중에 참조를 통해 값을 잡는 것이 좋습니다. 이 방법이 없으면 입력 필드를 현지 주 또는 플럭스 스토어로 최신 상태로 유지하기 위해 상당히 조정 된 프로세스를 거쳐야합니다. 이는 불필요 해 보입니다.

2019 년 편집 : 미래의 친구들 안녕하세요. 내가 몇 년 전에 언급 한 것 외에도 ^, React Hooks를 사용하면 ref는 렌더링 사이에 데이터를 추적하는 좋은 방법이며 DOM 노드를 잡는 것에 국한되지 않습니다.


답변

TL; DR 일반적으로 refsReact의 선언적 철학 에 위배 되므로 최후의 수단으로 사용해야합니다. state / props가능할 때마다 사용하십시오 .


어디 요 사용을 이해하기 위해 refs대를state / props , 반응하는 디자인 원칙의 일부에서 살펴 보자는 다음과 같습니다.

에 대한 React 문서refs

선언적으로 수행 할 수있는 모든 것에 refs를 사용하지 마십시오.

이스케이프 해치 에 대한 React의 설계 원칙

앱 빌드에 유용한 일부 패턴을 선언적 방식으로 표현하기 어려운 경우이를위한 명령형 API를 제공합니다. (그리고 그들은 여기에 심판에 연결됩니다)

즉, React의 팀 은 반응 적 / 선언적 방식으로 수행 할 수있는 모든 것을 피하고 refs사용하도록 제안합니다 state / props.

@Tyler McGinnis는 매우 좋은 답변 을 제공했습니다.

참조를 사용하는 올바른 (매우 유용한) 방법은 참조를 사용하여 DOM에서 값을 얻을 때입니다.

그렇게 할 수는 있지만 React의 철학에 반하게 될 것입니다. 입력에 가치가 있다면 가장 확실하게 state / props. 코드를 일관되고 예측 가능하게 유지하려면 state / props거기에도 충실해야 합니다. 나는 refs때때로 당신에게 더 빠른 해결책을 제공 한다는 사실을 인정합니다 . 그래서 당신이 개념 증명을한다면 빠르고 더럽습니다. 것은 받아 들일 수 있습니다.

이것은 우리에게 몇 가지 구체적인 사용 사례 를 남깁니다.refs

포커스, 텍스트 선택 또는 미디어 재생 관리. 명령형 애니메이션 트리거. 타사 DOM 라이브러리와 통합.


답변

이 게시물은 오래되었습니다.

나는 그 문제에 대한 한 가지 사례에 대한 나의 작은 경험을 공유 할 것입니다.

저는 많은 ‘동적’입력과 많은 캐시 된 데이터가 포함 된 큰 구성 요소 (414 줄)를 작업하고있었습니다. (나는 페이지에서 혼자 작업하지 않으며, 내 감각은 코드의 구조가 아마도 더 잘 분리 될 수 있다고 말해 주지만, 요점은 아닙니다 (글쎄, 그럴 수 있지만 처리하고 있습니다)

먼저 상태와 함께 입력 값을 처리했습니다.

  const [inputsValues, setInputsValues] = useState([])
  const setInputValue = (id, value) => {
    const arr = [...inputsValues]
    arr[id] = value
    setInputsValues(arr)
  }

그리고 물론 입력 :

value={inputsValues[id] || ''}
onChange={event => setInputValue(id, event.target.value)}

렌더링이 너무 무거워서 입력 변경이 ****처럼 고르지 않았습니다 (키를 누르지 마십시오. 텍스트는 일시 중지 후에 만 ​​나타납니다)

나는 심판을 사용하여 이것을 피할 수 있다고 확신했습니다.

다음과 같이 끝났습니다.

  const inputsRef = useRef([])

그리고 입력에서 :

ref={input => (inputsRef.current[id] = input)}

[제 경우에는 Input이 Material-UI TextField 였으므로 다음과 같습니다.

inputRef={input => (inputsRef.current[id] = input)}

]

덕분에 다시 렌더링하지 않고 입력이 부드럽습니다. 이 동일한 방식으로 작동합니다. 주기와 계산이 절약되므로 에너지도 절약됩니다. 지구를 위해 해 x)

내 결론 : 입력 값에 대한 useRef가 필요할 수도 있습니다.


답변