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
'source' 카테고리의 다른 글
| JavaScript 변수가 달러 기호로 시작하는 이유는 무엇입니까? (0) | 2022.11.12 |
|---|---|
| 여러 조인된 테이블에서 where 구에 사용자 지정 열을 사용합니다. (0) | 2022.11.12 |
| 캐스케이드 타입의 차이점은 무엇입니까?JPA에서 REMOVE 및 orphanRemoval? (0) | 2022.11.12 |
| Python이 해석되면 .pyc 파일이 뭐죠? (0) | 2022.11.12 |
| jQuery와 비동기적으로 파일을 업로드하려면 어떻게 해야 합니까? (0) | 2022.11.12 |