#Reactで親コンポーネントで子コンポーネントを変更する
Reactで親コンポーネントで子コンポーネントを変更する方法を記載します。
#VNodeを変更する
下記のようにChildren.toArray()を使って、children
をVNodeの配列に変換します。
isValidElement()でReact elementかどうかを判別します。
cloneElement()を使ってReact elementを変更します。
const root = createRoot(document.getElementById('app'));
function Parent({children, word}) {
const changedComponents = React.Children.toArray(children).map(c => {
if (React.isValidElement(c)) {
return React.cloneElement(c, {className: 'red'}, c.props.children + '2')
}
return c + word
})
return <div>{changedComponents}</div>
}
root.render(<Parent word="1">a<p>b</p>c</Parent>);
// a1
// b2
// c1
#子コンポーネント内の要素を参照する
下記のようにforwardRef()を使って、子コンポーネント内の要素を参照します。
import { forwardRef, useRef, useEffect } from 'react'
function _Child(_, ref) {
return <p ref={ref}>foo</p>
}
const Child = forwardRef(_Child)
function Parent() {
const ref = useRef(null)
useEffect(() => {
setTimeout(() => {
ref.current.textContent = 'bar'}, 1000)
}, [])
return <Child ref={ref} />
}
#子コンポーネント内で定義された関数を実行する
下記のようにuseImperativeHandle()を使って、子コンポーネント内で定義された関数を実行します。
import { forwardRef, useRef, useEffect, useImperativeHandle } from 'react'
function _Child(_, ref) {
const _ref = useRef(null)
useImperativeHandle(ref, () => {
return {
changeText() {
_ref.current.textContent = 'bar'
},
};
}, []);
return <p ref={_ref}>foo</p>
}
const Child = forwardRef(_Child)
function Parent() {
const ref = useRef(null)
useEffect(() => {
setTimeout(() => {
ref.current.changeText()
}, 1000)
}, [])
return <Child ref={ref} />
}