GOOGLE ADS

sábado, 30 de abril de 2022

Reaccionar .map y setState comportamiento extraño

La siguiente es una versión simplificada de la parte del código completo.

Básicamente, se supone que toda la aplicación es una aplicación para tomar notas creada en React, y actualmente estoy atascado en la función de edición de sus respectivas notas.

Entonces, la siguiente parte del script básicamente es compatible para hacer:

  • Representar una matriz de <Card />componentes basada en la this.state.notesmatriz de la aplicación

  • Al hacer clic en el Edit notebotón, establece el this.state.noteEditingIdestado de la aplicación

  • (para que la instancia de React pueda saber más tarde qué Tarjeta generada está siendo editada actualmente por la identificación)

  • Al hacer clic en el Save Editbotón, intenta actualizar la this.state.notesmatriz de la aplicación con el texto de edición enviado.

  • (Mira, usé muchos filtros para tratar de lograr esto, ya que no tengo una buena idea de cómo lograrlo mejor. Creo que debería haber una manera mejor)

  • Pero el resultado no es el que esperaba.

  • (Si bien se suponía que lograría actualizar la matriz de notas del componente Card esperado con el texto de "nota" de la nueva instancia de nota, actualiza la matriz de notas con el texto de "nota" de la instancia de nota de las diferentes notas. No puedo explicar esto claramente, ya que esto es un problema del tipo no sé qué es lo que está mal para mí).


    const Card = (props) => {
    const [noteEditing, setNoteEditing] = useState(false);
    return (
    <div {...props}>
    <div>
    <div>
    <span>
    <button onClick={() => {
    noteEditing? setNoteEditing(false): setNoteEditing(true);
    props.thisApp.setState({ noteEditingId: props.config.id })
    }}>Edit note</button>
    </span>

    {noteEditing
    ?
    <div>
    <textarea className='__text' />
    <button onClick={() => {
    let note = document.querySelector('.__text').value
    let current_note = props.thisApp.state.notes.filter(a => a.id == props.config.id)[0]
    let notesAfterRemoved = props.thisApp.state.notes.filter(a => a.id!== props.config.id)
    if (props.thisApp.state.noteEditingId == props.config.id)
    {
    props.thisApp.setState({
    notes: [...notesAfterRemoved, {...current_note, note: note }]
    })
    }
    }}>
    Save Edit
    </button>
    </div>
    : ""
    }
    </div>
    </div>
    </div>
    )
    }
    class App extends React.Component {
    constructor() {
    super();
    this.state = {
    notes: [
    {
    note: "note1.",
    id: nanoid(),
    },
    {
    note: "note2.",
    id: nanoid(),
    },
    {
    note: "note3.",
    id: nanoid(),
    },
    ]
    };
    }
    render() {
    return (
    <div>
    <h2>
    Notes ({this.state.notes.length})
    </h2>
    <div className='__main_cards'>
    <div>
    {this.state.notes.map((a, i) => {
    return <Card key={i} className="__card" thisApp={this} config={
    {
    note: a.note,
    }
    } />
    })}
    </div>
    </div>
    </div>
    )
    }
    }

    Entonces, ¿qué puedo hacer para que la pieza funcione correctamente? Gracias.


    Solución del problema

    También debe pasar la nota actual y deshacerse del filtro en el componente de la tarjeta:

    this.state.notes.map((note, i) => {
    return (
    <Card
    key={i}
    className="__card"
    thisApp={this}
    currentNote={note}
    />
    );
    })

    Y luego elimina esto:

    let current_note = props.thisApp.state.notes.filter(a => a.id == props.config.id)[0]

    Y luego, en lugar de encontrar las notas sin la nota editada, puede crear una nueva matriz con datos editados como este:

    const x = props.thisApp.state.notes.map((n) => {
    if (n.id === props.currentNote.id) {
    return {...n, note}
    }
    return n
    })

    Y deshazte de esta línea:

    let notesAfterRemoved = props.thisApp.state.notes.filter(a => a.id!== props.config.id)

    Además, cambia esto

    noteEditing? setNoteEditing(false): setNoteEditing(true);

    Para:

    setNoteEditing(prev =>!prev)

    Como es una forma mucho más limpia de alternar el valor.

    Y creo que no hay necesidad de verificar si el noteEditingId es igual al ID de la nota activa actual.

    Así que también puedes deshacerte de eso (¡Corrígeme si me equivoco!)

    Here's the full code:


    const Card = (props) => {
    const [noteEditing, setNoteEditing] = useState(false);
    const textareaRef = useRef();
    return (
    <div {...props}>
    <div>
    <div>
    <span>
    <button
    onClick={() => {
    setNoteEditing((prev) =>!prev); // Cleaner way to toggle
    }}
    >
    Edit note
    </button>
    </span>
    {noteEditing && (
    <div>
    <textarea className="__text" ref={textareaRef} />
    <button
    onClick={() => {
    let note = textareaRef.current.value;
    const x = props.thisApp.state.notes.map(
    (n) => {
    if (n.id === props.currentNote.id) {
    return {...n, note };
    }
    return n;
    }
    );
    props.thisApp.setState({
    notes: x,
    });
    }}
    >
    Save Edit
    </button>
    </div>
    )}
    </div>
    </div>
    </div>
    );
    };
    class App extends React.Component {
    constructor() {
    super();
    this.state = {
    notes: [
    {
    note: "note1.",
    id: nanoid(),
    },
    {
    note: "note2.",
    id: nanoid(),
    },
    {
    note: "note3.",
    id: nanoid(),
    },
    ],
    };
    }
    render() {
    return (
    <div>
    <h2>Notes ({this.state.notes.length})</h2>
    <div className="__main_cards">
    <div>
    {this.state.notes.map((note, i) => {
    return (
    <Card
    key={i}
    className="__card"
    thisApp={this}
    currentNote={note}
    />
    );
    })}
    </div>
    </div>
    </div>
    );
    }
    }
    }
    );
    props.thisApp.setState({
    notes: x,
    });
    }
    }}
    >
    Save Edit
    </button>
    </div>
    )}
    </div>
    </div>
    </div>
    );
    };
    class App extends React.Component {
    constructor() {
    super();
    this.state = {
    notes: [
    {
    note: "note1.",
    id: nanoid(),
    },
    {
    note: "note2.",
    id: nanoid(),
    },
    {
    note: "note3.",
    id: nanoid(),
    },
    ],
    };
    }
    render() {
    return (
    <div>
    <h2>Notes ({this.state.notes.length})</h2>
    <div className="__main_cards">
    <div>
    {this.state.notes.map((note, i) => {
    return (
    <Card
    key={i}
    className="__card"
    thisApp={this}
    currentNote={note}
    />
    );
    })}
    </div>
    </div>
    </div>
    );
    }
    }

    ¡Espero que esto sea útil para usted!

    No hay comentarios.:

    Publicar un comentario

    Flutter: error de rango al acceder a la respuesta JSON

    Estoy accediendo a una respuesta JSON con la siguiente estructura. { "fullName": "FirstName LastName", "listings...