Hago un código de prueba. Se agregó selectorFamily de Recoil para configurar el estado con nombres. Se utilizará en el futuro para obtener algunos nombres de la API con la página proporcionada.
Los nombres se enumeran a continuación en la etiqueta de listado y un botón.
Cuando hace clic en el botón, cambiará el valor del segundo nombre, pero recibo el error: "Intento de establecer el valor de retroceso de solo lectura: selectorFamily", no puedo entender qué estoy haciendo mal con este código:
import { selectorFamily, useRecoilState } from "recoil"; const namesState = selectorFamily({ key: 'names', get: (page) => ({ get }) => { let data = [ { name: 'Tom' }, { name: 'John' }, { name: 'Jane' } ]; return data; } }); const ChangeName = () => { const [names, setNames] = useRecoilState(namesState(3)); const changeSecondName = () => { let newNames = [...names].map((data, i) => { let newData = { ...data }; if (i === 1) { newData.name = 'Steve'; } return newData; }); setNames(newNames); }; return ( <div> <ul> {names.map((item) => { return ( <li key={item.name}>{item.name}</li> ); })} </ul> <button onClick={changeSecondName}>Change second name to Steve</button> </div> ); }; export default ChangeName;el código es simple, solo intento cómo puedo cambiar algún valor en el objeto que está en la matriz.
Gracias
Para poder llamar a useRecoilState en el selector, debe usar un átomo o un selector escribible (selector que tiene un método establecido). No tiene el método establecido implementado en su familia de selectores. Considere usar la familia de átomos en su lugar.
logro trabajar. Se agregó un nuevo estado escribible como dijo @shobe. También se agregó useEffiect para obtener y completar el estado de atomNames por primera vez:
import { useEffect } from "react"; import { selectorFamily, useRecoilState, atom } from "recoil"; const namesAtomState = atom({ key: 'atomNames', default: [] }); const namesState = selectorFamily({ key: 'names', get: (page) => ({ get }) => { let data = [ { name: 'Tom' }, { name: 'John' }, { name: 'Jane' } ]; return data; } , set: () => ({ set, get }, value) => { const names = get(namesState(2)); let newNames = [...names].map((data, i) => { let newData = { ...data }; if (i === 1) { newData.name = 'Steve'; } return newData; }); set(namesAtomState, newNames); } }); const ChangeName = () => { const [namesAtom, setNamesAtom] = useRecoilState(namesAtomState); const [names, setNames] = useRecoilState(namesState(2)); // Update state when AJAX return values useEffect(()=>{ if (names) { setNamesAtom(names); } },[names, setNamesAtom]); // Set new name for second value in array const changeSecondName = () => { setNames(2); }; return ( <div> <ul> {namesAtom.map((item) => { return ( <li key={item.name}>{item.name}</li> ); })} </ul> <button onClick={changeSecondName}>Change second name to Steve</button> </div> ); }; export default ChangeName;