source

React에서 자녀의 상태에 액세스하는 방법

bestscript 2022. 11. 12. 08:29

React에서 자녀의 상태에 액세스하는 방법

다음과 같은 구조를 가지고 있습니다.

FormEditor - FieldEditor의 되어 있습니다.FieldEditor- 폼의 필드를 편집하여 폼의 다양한 값을 폼 상태에 저장합니다.

버튼을 FormEditor에서 에 대한 할 수 .FieldEditor포넌 、 그 formitoritor 、 FormEditor 、 form formitoritoritoritoritor 。

는 이 밖에 있는 에 대한 했습니다.FieldEditor의 을 에 FormEditor대신 의 상태를 나타냅니다., 위해서는 「」, 「」가 필요합니다.FormEditorFieldEditor컴포넌트가 변경 및 정보를 해당 상태로 저장할 때 사용합니다.

대신 아이들의 주(州)에 접속하면 안 돼요?이상적이야?

자 컴포넌트 상태에 액세스하는 방법에 대해 자세히 설명하기 전에 이 특정 시나리오에 대처하기 위한 더 나은 솔루션에 대한 Markus-ipse의 답변을 꼭 읽어보시기 바랍니다.

하고 는, 「자녀의 상태」라고 하는 할 수 .ref각 아이에게요.참조를 실장하는 방법에는, 다음의 2가지가 있습니다.「」를 사용합니다.React.createRef()아, 아, 아, 아, 아, 아, 아, 네.

「」를 사용합니다.React.createRef()

이는 현재 React 16.3에서 참조를 사용하는 데 권장되는 방법입니다(자세한 내용은 설명서를 참조하십시오).이전 버전을 사용하는 경우 콜백 레퍼런스에 대해 아래를 참조하십시오.

한 후 ref여하하다

class FormEditor extends React.Component {
  constructor(props) {
    super(props);
    this.FieldEditor1 = React.createRef();
  }
  render() {
    return <FieldEditor ref={this.FieldEditor1} />;
  }
}

이러한 종류의 레퍼런스에 액세스 하려면 , 다음을 사용할 필요가 있습니다.

const currentFieldEditor1 = this.FieldEditor1.current;

마운트된 가 반환되므로 이 마운트된 할 수 .currentFieldEditor1.state을 사용하다

를 들어 DOM 노드)에 하겠습니다.<div ref={this.divRef} />) 그 、 。this.divRef.current는 컴포넌트 인스턴스 대신 기본 DOM 요소를 반환합니다.

콜백 레퍼런스

이 속성은 연결된 구성 요소에 대한 참조가 전달된 콜백 함수를 사용합니다.이 콜백은 컴포넌트가 마운트 또는 마운트 해제된 직후 실행됩니다.

예를 들어 다음과 같습니다.

<FieldEditor
    ref={(fieldEditor1) => {this.fieldEditor1 = fieldEditor1;}
    {...props}
/>

이러한 예에서는 참조가 부모 컴포넌트에 저장됩니다.코드의 이 컴포넌트를 호출하려면 다음 명령을 사용합니다.

this.fieldEditor1

그런 다음 사용this.fieldEditor1.state주(州)를 얻기 위해.

한 가지 유의할 점은 하위 구성요소에 액세스하기 전에 렌더링되었는지 확인하십시오^_^

위와 같이 컴포넌트가 아닌 DOM 노드에서 이러한 참조를 사용하는 경우(예:<div ref={(divRef) => {this.myDiv = divRef;}} />)그럼this.divRef는 컴포넌트 인스턴스 대신 기본 DOM 요소를 반환합니다.

추가정보

React의 ref 속성에 대한 자세한 내용은 페이스북에서 확인하시기 바랍니다.

어린이용 레퍼런스 과다사용 금지 섹션을 반드시 읽으십시오.state'실현'을 할 수 있게 해주세요.

이미 개별 FieldEditor에 대한 onChange 핸들러가 있는 경우 상태를 FormEditor 컴포넌트로 이동하여 콜백을 FieldEditor에서 FieldEditor로 전달하여 부모 상태를 갱신할 수 없는 이유를 알 수 없습니다.나한테는 그게 더 리액트한 방법인 것 같아

이와 비슷한 점이 있을 수 있습니다.

const FieldEditor = ({ value, onChange, id }) => {
  const handleChange = event => {
    const text = event.target.value;
    onChange(id, text);
  };

  return (
    <div className="field-editor">
      <input onChange={handleChange} value={value} />
    </div>
  );
};

const FormEditor = props => {
  const [values, setValues] = useState({});
  const handleFieldChange = (fieldId, value) => {
    setValues({ ...values, [fieldId]: value });
  };

  const fields = props.fields.map(field => (
    <FieldEditor
      key={field}
      id={field}
      onChange={handleFieldChange}
      value={values[field]}
    />
  ));

  return (
    <div>
      {fields}
      <pre>{JSON.stringify(values, null, 2)}</pre>
    </div>
  );
};

// To add the ability to dynamically add/remove fields, keep the list in state
const App = () => {
  const fields = ["field1", "field2", "anotherField"];

  return <FormEditor fields={fields} />;
};

오리지널 - 프리 훅 버전:

class FieldEditor extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    const text = event.target.value;
    this.props.onChange(this.props.id, text);
  }

  render() {
    return (
      <div className="field-editor">
        <input onChange={this.handleChange} value={this.props.value} />
      </div>
    );
  }
}

class FormEditor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};

    this.handleFieldChange = this.handleFieldChange.bind(this);
  }

  handleFieldChange(fieldId, value) {
    this.setState({ [fieldId]: value });
  }

  render() {
    const fields = this.props.fields.map(field => (
      <FieldEditor
        key={field}
        id={field}
        onChange={this.handleFieldChange}
        value={this.state[field]}
      />
    ));

    return (
      <div>
        {fields}
        <div>{JSON.stringify(this.state)}</div>
      </div>
    );
  }
}

// Convert to a class component and add the ability to dynamically add/remove fields by having it in state
const App = () => {
  const fields = ["field1", "field2", "anotherField"];

  return <FormEditor fields={fields} />;
};

ReactDOM.render(<App />, document.body);

앞의 답변에서 설명한 바와 같이 상태를 상위 컴포넌트로 이동하고 콜백을 통해 상태를 변경합니다.

기능 컴포넌트(훅)로 선언된 자녀 상태에 액세스할 필요가 있는 경우 부모 컴포넌트에서 ref를 선언한 후 이를 자녀에게 ref 속성으로 전달할 수 있습니다.단, React.forwardRef를 사용한 후 은 ImperativeHandle을 사용하여 부모 컴포넌트에서 호출할 수 있는 함수를 선언해야 합니다.

다음의 예를 참조해 주세요.

const Parent = () => {
    const myRef = useRef();
    return <Child ref={myRef} />;
}

const Child = React.forwardRef((props, ref) => {
    const [myState, setMyState] = useState('This is my state!');
    useImperativeHandle(ref, () => ({getMyState: () => {return myState}}), [myState]);
})

다음으로 다음 콜을 통해 Parent 컴포넌트에서 myState를 얻을 수 있습니다.

myRef.current.getMyState();

지금은 2020년입니다.여러분들도 비슷한 솔루션을 찾고 계시겠지만 Hooks(훌륭합니다!)와 코드 청결도 및 구문 면에서 최신 접근 방식을 사용하고 있습니다.

따라서 이전 답변에서 설명한 바와 같이 이러한 문제에 대한 최선의 접근법은 상태를 하위 구성요소 외부에 유지하는 것입니다.fieldEditor여러 가지 방법으로 할 수 있습니다.

가장 "복잡한" 것은 부모와 자녀 모두 액세스하여 수정할 수 있는 글로벌 컨텍스트(상태)입니다.이 솔루션은 컴포넌트가 트리 계층에 깊이 들어가 있기 때문에 각 레벨에 소품을 보내는 데 비용이 많이 듭니다.

그럴하고, 좀 더 수 있을 것요. , 하다, 하다, 하다, 하다, 하다, 하다, 하다.강력한 테크놀로지를 사용하는 것만으로React.useState().

React.useState() 후크를 사용한 접근법 - 클래스 컴포넌트보다 훨씬 단순합니다.

설명한 바와 같이 컴포넌트의 를 저장합니다.fieldEditorfieldForm, 우리는 이 기능에 을 적용합니다.fieldForm스테이트에서는, 다음의 조작을 실시할 수 있습니다.

function FieldForm({ fields }) {
  const [fieldsValues, setFieldsValues] = React.useState({});
  const handleChange = (event, fieldId) => {
    let newFields = { ...fieldsValues };
    newFields[fieldId] = event.target.value;

    setFieldsValues(newFields);
  };

  return (
    <div>
      {fields.map(field => (
        <FieldEditor
          key={field}
          id={field}
          handleChange={handleChange}
          value={fieldsValues[field]}
        />
      ))}
      <div>{JSON.stringify(fieldsValues)}</div>
    </div>
  );
}

:React.useState({})는 위치 0이 호출 시 지정된 값(이 경우 빈 개체)이고 위치 1이 값을 변경하는 함수에 대한 참조인 배열을 반환합니다.

컴포넌트와 '자 컴포넌트'를 선택합니다.FieldEditor스테이트먼트를 필요도 return 스테이트먼트를 사용하면 함수를 만들 수 .화살표 기능이 있는 린 상수면 충분합니다!

const FieldEditor = ({ id, value, handleChange }) => (
  <div className="field-editor">
    <input onChange={event => handleChange(event, id)} value={value} />
  </div>
);

아,, 우우끝끝끝. 그 이상은 아니야.두 목표는 '접근.FieldEditor부모에게 자랑할 수 있는 기회입니다.

5년 전에 인정된 답변을 확인하고 Hooks가 리액트 코드를 어떻게 (많이!) 얇게 만들었는지 확인할 수 있습니다.

제 답변이 Hooks에 대해 더 많은 것을 배우고 이해하는 데 도움이 되기를 바랍니다.실행 예를 확인하시려면 여기 있습니다.

이제 FormEditor의 하위 항목인 InputField 상태에 액세스할 수 있습니다.

기본적으로 입력 필드(자녀) 상태가 변경될 때마다 이벤트 개체에서 값을 가져와 이 값을 부모 상태로 전달합니다.

버튼 클릭 한 번으로 입력 필드 상태를 인쇄합니다.

여기서 중요한 점은 소품을 사용하여 입력 필드의 ID/값을 가져오고 재사용 가능한 자식 입력 필드를 생성하는 동안 입력 필드의 속성으로 설정된 함수를 호출한다는 것입니다.

class InputField extends React.Component{
  handleChange = (event)=> {
    const val = event.target.value;
    this.props.onChange(this.props.id , val);
  }

  render() {
    return(
      <div>
        <input type="text" onChange={this.handleChange} value={this.props.value}/>
        <br/><br/>
      </div>
    );
  }
}


class FormEditorParent extends React.Component {
  state = {};
  handleFieldChange = (inputFieldId , inputFieldValue) => {
    this.setState({[inputFieldId]:inputFieldValue});
  }
  // On a button click, simply get the state of the input field
  handleClick = ()=>{
    console.log(JSON.stringify(this.state));
  }

  render() {
    const fields = this.props.fields.map(field => (
      <InputField
        key={field}
        id={field}
        onChange={this.handleFieldChange}
        value={this.state[field]}
      />
    ));

    return (
      <div>
        <div>
          <button onClick={this.handleClick}>Click Me</button>
        </div>
        <div>
          {fields}
        </div>
      </div>
    );
  }
}

const App = () => {
  const fields = ["field1", "field2", "anotherField"];
  return <FormEditorParent fields={fields} />;
};

ReactDOM.render(<App/>, mountNode);

자 컴포넌트에 콜백을 전달함으로써 자 스테이트에 액세스 할 수 있습니다.

const Parent = () => {
  return (
    <Child onSubmit={(arg) => { 
             console.log('accessing child state from parent callback: ', arg) 
           }} 
    /> 
  )
}

const Child = ({onSubmit}) => {
    const [text, setText] = useState('');

    return (
      <>
        <input value={text} onChange={setText}>
        <button onClick={() => onSubmit(search)} />
      </>
    )
}

이제 하위 구성요소의 버튼을 클릭하면 상위 구성요소에서 전달된 함수를 실행하고 하위 구성요소의 상태 변수에 액세스할 수 있습니다.

언급URL : https://stackoverflow.com/questions/27864951/how-to-access-a-childs-state-in-react