reactjs - ¿Cómo puedo obtener todos los estados de los hijos desde el elemento padre?
¿Cómo puedo obtener todos los estados de los hijos desde el elemento padre?
Creé una página, y hay algunos elementos, el más importante es esta lista de componentes.
Aquí está el elemento padre:
const Home = () => {
const walls = [1, 2, 3, 4];
return (
<Layout>
{walls.map(wall => {
return <Wall key={wall} index={wall} />;
})}
</Layout>
);
};
Como puedes ver, genera una lista de elementos con map.
Entonces, ¿cómo puedo obtener todos los estados de los hijos desde el elemento padre?
Este es el componente hijo:
const Wall = ({ index }: IWall) => {
const { doors, windows, handleWindows, handleDoors } =
useWall();
return (
<div>
<input .../>
<input .../>
...
</div>
);
};
Y sus ganchos:
export const useWall = () => {
const [doors, setDoors] = useState(0);
const [windows, setWindows] = useState(0);
const handleWindows = (value: number) => {
if (value < 0 || value > 50) return;
setWindows(value);
};
const handleDoors = (value: number) => {
if (value < 0 || value > 50) return;
setDoors(value);
};
return { doors, windows, handleWindows, handleDoors };
};
Respuesta #1
Generalmente se considera un anti-patrón en React que los componentes padres accedan a los componentes hijos para acceder a su estado y funciones. La solución es Elevar el Estado al componente padre y pasar el estado y las funciones de actualización del estado como props hacia los componentes hijos.
Ejemplo :
const Home = () => {
const [walls, setWalls] = useState<IWall[]>(
[1, 2, 3, 4].map((id) => ({
id,
doors: 0,
windows: 0
}))
);
const changeHandler = (id: number) => (
e: React.ChangeEvent<HTMLInputElement>
) => {
const { name, value } = e.target;
if (Number(value) >= 0 && Number(value) <= 50) {
setWalls((walls) =>
walls.map((wall) =>
wall.id === id ? { ...wall, [name]: value } : wall
)
);
}
};
return (
<Layout>
{walls.map((wall) => {
return (
<Wall
key={wall.id}
wall={wall}
changeHandler={changeHandler(wall.id)}
/>
);
})}
</Layout>
);
};
...
interface IWall {
id: number;
doors: number;
windows: number;
}
interface WallProps {
wall: IWall;
changeHandler: React.ChangeEventHandler<HTMLInputElement>;
}
const Wall = ({ changeHandler, wall }: WallProps) => {
return (
<div>
<h2>Wall: {wall.id}</h2>
<label>
Doors
<input
name="doors"
type="number"
value={wall.doors}
onChange={changeHandler}
/>
</label>
<label>
Windows
<input
name="windows"
type="number"
value={wall.windows}
onChange={changeHandler}
/>
</label>
</div>
);
};
