반응 - 여러 참조 전달
인접 html 테이블(InfoTable) 내의 대응하는 헤더로 스크롤해야 하는 동적으로 생성된 링크를 포함하는 SideNav 컴포넌트가 있습니다.나는 이것을 이루기 위해 여러 가지 다른 방법을 시도해봤지만 소용이 없었다.
export default class Parent extends Component {
state = {
categories: [],
}
scrollToHeader = (tableRefString) => {
// Function to pass to SideNav to access refs in InfoTable
this[tableRefString].scrollIntoView({ block: 'start' });
}
render() {
return (
<div>
<SideNav
categories={this.state.categories}
scrollToHeader={this.scrollToHeader} />
<InfoTable
categories={this.state.categories} />
</div>
);
}
}
export default class InfoTable extends Component {
render() {
return (
<div>
<table>
<tbody>
{this.props.categories.map(category => (
<>
// Forward the ref through InfoTableHeader to be set on the parent DOM node of each InfoTableHeader
<InfoTableHeader />
{category.inputs.map(input => <InfoTableRow />)}
</>
))}
</tbody>
</table>
</div>
);
}
}
SideNav에서 링크를 클릭하여 InfoTable에서 대응하는 헤더로 스크롤하려면 카테고리 배열의 이름을 기반으로 부모 상에서 동적으로 작성된 참조를 전송하고 이러한 참조를 InfoTable의 각 헤더에 대해 DOM 노드에 설정해야 합니다.여기서부터 SideNav로 이동하여 헤더까지 스크롤할 수 있는 기능을 Parent의 ref에 액세스 할 수 있습니다.
- 여러 참조를 InfoTable 컴포넌트로 한 번에 전송하려면 어떻게 해야 합니까?
- 제가 하려는 일을 더 깔끔하게 해낼 수 있는 방법이 있을까요?React.findDOMNode()에 대해 알아보았지만 참조가 더 나은 옵션인 것 같습니다.
이미 받아들여진 답변이 있다는 것을 알고 있지만, @nicholas-haley의 솔루션은 받아들일 수 있습니다.더 좋은 방법은 빌트인을 사용하는 것입니다.useImperativeHandle
중요: React Hooks API는 현재 제공되고 있습니다.
- react@16.8.0 이후
- react-displays@0.59.0 이후
React hooks API Docs 상태는 다음과 같습니다.
useImperativeHandle
는 ref를 사용할 때 상위 컴포넌트에 노출되는 인스턴스 값을 사용자 정의합니다.은 forwardRefuseImperativeHandle 'forwardRef'와 함께.
이 주의에는 다음 예가 뒤따릅니다.
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
때문에 제가 때 더 이 될 것 같습니다.useImperativeHandle
이렇게 하면 특별한 ref 구문이 필요하지 않으며 컴포넌트는 단순히 특정 유형의 FatherRef를 반환할 수 있습니다.예:
// LabelInput.js
function LabelInput(props, ref) {
const labelRef = useRef();
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
get input() {
return inputRef.current;
},
get label() {
return labelRef.current;
},
// ... whatever else one may need
}));
return (
<div>
<label ref={labelRef} ... />
<input ref={inputRef} ... />;
</div>
)
}
LabelInput = forwardRef(LabelInput);
function MyScreen() {
const labelInputRef = useRef();
const onClick = useCallback(
() => {
// labelInputRef.current.focus(); // works
// labelInputRef.current.input.focus(); // works
// ... etc
},
[]
);
return (
...
<LabelInput ref={labelInputRef} ... />
....
)
}
비슷한 상황에서 여러 명의 레퍼런스를 부모 컴포넌트의 자녀에게 전송해야 했습니다.
해결책을 해, 할 수 .forwardRef
★★★★
// Parent
ref={{
ref1: this.ref1,
ref2: this.ref2
}}
// Child
export default React.forwardRef((props, ref) => {
const { ref1, ref2 } = ref;
return (
<Child1
{...props}
ref={ref1}
/>
<Child2
{...props}
ref={ref2}
/>
);
});
는 여기 붙이는 좋아하지 않습니다.ref
refs
할 수 있습니다.) 라고 말합니다.
편집:
2020년에는 @samer-murad의 답변이 이 문제에 대한 최선의 해결책이라고 생각합니다.
리액트 훅 폼에서 이것을 집어들었습니다만, 레퍼런스를 공유해, 동시에 복수의 레퍼런스를 할당할 수 있는 좋은 방법을 제시했습니다.
<input name="firstName" ref={(e) => {
register(e) // use ref for register function
firstNameRef.current = e // and you can still assign to ref
}} />
난 아직도 그 안에서 무슨 일이 벌어지는지 모르겠어ref
속성. 단, 다음과 같습니다.React
source code type of type.type === 'function' + 기타 답변으로 인해 다음 테스트를 통과했습니다.function
의hoisted refs
부터parent
, 그리고 효과가 있습니다!
class Child extends React.Component {
render() {
return (
<div>
<div
ref={this.props.pa}
style={this.props.style}
onClick={async () => {
this.storeAuth(...this.props.storableAuth);
this.props.clearStore();
}}
/>
<div
ref={this.props.fwd}
style={this.props.style}
onClick={async () => {
this.props.onStart();
const res = await this.getUserInfo(verbose, auth, storedAuth);
if (res === "login?") this.props.onPromptToLogin();
if (res) this.props.onFinish(); //res.isAnonymous
}}
/>
</div>
);
}
}
export default React.forwardRef((props, getRefs) => {
const { pa, fwd } = props.getRefs();
return <Child fwd={fwd} pa={pa} {...props} />;
});
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.pa = React.createRef();
this.fwd = React.createRef();
}
render() {
return (
<Child
getRefs={() => {
return {
pa: this.pa,
fwd: this.fwd
};
}}
storableAuth={this.state.storableAuth}//[]
clearAuth={() => this.setState({ storableAuth: null })}
/>
);
}
}
이 질문의 작성자가 질문한 내용은 아니지만, 이 제목도 이 질문의 발단이 될 수 있습니다.React 컴포넌트를 사용하는 개발자가 내 컴포넌트에 내부 참조를 통과했을 때 참조를 통과하도록 허용하는 방법(즉, 이 컴포넌트에 대한 참조를 여러 개 통과시키는 방법)입니다.
이것이 제가 가지고 온 해결책입니다.
import { useState, useRef } from "react";
export default function App() {
const [, render] = useState({});
const reRender = () => render({});
const divRef = useRef();
console.log("App", divRef);
return <Component reRender={reRender} passPropsToDiv={{ ref: divRef }} />;
}
const Component = ({ passPropsToDiv, reRender }) => {
const div1Ref = useRef();
const { ref: extraRef = null, ...passPropsToDivNoRef } = passPropsToDiv ?? {};
extraRef.current = div1Ref.current;
console.log("Component", div1Ref);
return (
<div className="App">
<div ref={div1Ref} {...passPropsToDivNoRef}>
i will have a ref
</div>
<button onClick={reRender}>reRender</button>
</div>
);
};
codesandbox: https://codesandbox.io/s/react-use-pass-multiple-refs-legm7p?file=/src/App.js
언급URL : https://stackoverflow.com/questions/53561913/react-forwarding-multiple-refs
'programing' 카테고리의 다른 글
AngualrJ: html 갱신 시 데이터 유지 (0) | 2023.03.08 |
---|---|
Oracle 더하기(+) 표기법과 ANSI JOIN 표기법의 차이점 (0) | 2023.03.08 |
json을 사용하여 복잡한 유형을 ASP에 전달하는 방법.NET MVC 컨트롤러 (0) | 2023.03.08 |
스프링 주석 @Controller는 @Service와 동일합니까? (0) | 2023.03.03 |
wpdb를 사용하여 데이터를 삽입하는 방법 (0) | 2023.03.03 |