JSFiddle - React, Tailwind, and code Playground
HTML
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>
Babel + JSX
const { useState, useEffect, useCallback, useRef, forwardRef } = React;
const Xxx = forwardRef(({ num, onClick }, ref) => {
useEffect(() => {
ref({
xxx: () => alert(`xxx: ${num}`),
});
}, []);
return (
<div>
<span data-num={num}>item #{num}</span>
<button onClick={onClick}>click me</button>
</div>
);
});
function XxxGroup({ num }) {
const refs = useRef([]);
useEffect(() => {
//refs.current = Array(num).fill(null);
refs.current = refs.current.slice(0, num);
}, [ num ]);
const setRef = (el, index) => {
refs.current[index] = el;
};
const onClick = useCallback((index) => {
refs.current[index].xxx();
}, []);
return (
<div>
{Array.from({ length: num }, (_, i) => (
<Xxx
num={i}
ref={(el) => setRef(el, i)}
onClick={() => onClick(i)}
/>
))}
<hr />
<button onClick={() => console.log(refs.current)}>log all</button>
</div>
);
}
function App({ strings, objects }) {
const [ num, setNum ] = useState(2);
const updateNum = e =>
setNum(Math.max(0, Math.min(10, num + +e.target.dataset.step)));
return (<>
<input value={num} />
<button onClick={updateNum} data-step="-1">-</button>
<button onClick={updateNum} data-step="+1">+</button>
<XxxGroup num={num} />
</>);
}
ReactDOM
.createRoot(document.querySelector('#root'))
.render( <App />);