¿Cómo editar un artículo en una matriz de estado? -- reactjs camp Relacionados El problema

How to edit an item in a state array?


28
vote

problema

Español

Así que aquí está mi estado:

  this.state = {   ids: ['A', 'E', 'C'] };   

¿Cómo voy a modificar el estado para que 'E' en el índice 1 se cambie a 'B'? Como por ejemplo:

  this.setState({   ids[1]: 'B' });   

¿Cómo se hará esto?

Original en ingles

So here is my state:

this.state = {   ids: ['A', 'E', 'C'] }; 

How would I go about modifying the state so that 'E' at index 1 is changed to 'B'? Like for example:

this.setState({   ids[1]: 'B' }); 

How would this be done?

  
 
 

Lista de respuestas

61
 
vote
vote
La mejor respuesta
 

Mi sugerencia es acostumbrarse a usar operaciones inmutables, por lo que no modifica el objeto del estado interno.

Como se señaló en la reaccionar documentos :

Nunca muta esto. Estado directamente, ya que Llame FetState () Posteriormente puede Reemplaza la mutación que hiciste. tratar este estado como si fuera inmutable.

En este caso, puede [1] usar slice() Para obtener una nueva copia de la matriz, [2] manipular la copia , y, entonces, [3] setstate con la nueva matriz. Es una buena práctica.

algo así:

  const newIds = this.state.ids.slice() //copy the array newIds[1] = 'B' //execute the manipulations this.setState({ids: newIds}) //set the new state   
 

My suggestion is to get used to use immutable operations, so you don't modify internal state object.

As pointed in the react docs:

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

In this case, you can [1] use slice() to get a new copy of the Array, [2] manipulate the copy, and, then, [3] setState with the new Array. It's a good practice.

Something like that:

const newIds = this.state.ids.slice() //copy the array newIds[1] = 'B' //execute the manipulations this.setState({ids: newIds}) //set the new state 
 
 
       
       
27
 
vote

Case 1: Si conoce el índice, entonces puede escribirlo así:

  let ids = [...this.state.ids];     // create the copy of state array ids[index] = 'k';                  //new value this.setState({ ids });            //update the value   

Case 2: Si no conoce el índice, entonces primero use Array.FindIndex o cualquier otro bucle para obtener el índice del elemento que desea actualizar, después de eso, actualice el valor y use estadaje.

Me gusta esto:

  let ids = [...this.state.ids];   let index = ids.findIndex(el => /* condition */); ids[index] = 'k';                   this.setState({ ids });               
 

Case 1: If you know the index then you can write it like this:

let ids = [...this.state.ids];     // create the copy of state array ids[index] = 'k';                  //new value this.setState({ ids });            //update the value 

Case 2: If you don't know the index then first use array.findIndex or any other loop to get the index of item you want to update, after that update the value and use setState.

Like this:

let ids = [...this.state.ids];   let index = ids.findIndex(el => /* condition */); ids[index] = 'k';                   this.setState({ ids });             
 
 
4
 
vote

Aquí hay otra solución para cambiar un índice específico de matriz en un estado de set:

  this.setState({   ...array,   Object.assign([...array], { [id]: yourNewObjectOrValue }) })   
 

Here is another solution to change a specific index of array in a setState:

this.setState({   ...array,   Object.assign([...array], { [id]: yourNewObjectOrValue }) }) 
 
 
1
 
vote

Edificio en lo que escribió @ Mayank-Shukla (Caso 2: conocer el índice del artículo para reemplazar), esto también podría escribirse con matray.splice :

  const replacement = 'B'; let copy = [...this.state.ids] copy.splice(index, 1, replacement)  this.setState({     ids: copy, })   

Ejemplo de respuesta

Dos cosas para notar, aquí:

  1. Array.splice es mutativo; Cambiará la matriz en funcionamiento, pero esta es una copia poco profunda de la matriz debido al operador de distribución. Más sobre eso a continuación.
  2. No puede asignar directamente el resultado de un empalme, ya que el valor de retorno de Array.splice es en realidad el elemento (s) eliminado . AKA: No asigne el resultado de su rebanada a la variable que tiene la intención de asignar a las IDS en setState , o terminará con solo el (los) valor (s) eliminado (s).

Para realizar un seguimiento de las copias profundas de Solof VS del artículo 1, tenga en cuenta que si está reemplazando las referencias de objetos (vs literales de cadena en la pregunta), deberá usar algo como Lodash's Clonedeep .

Hay una puñado de otras maneras alrededor esto , sin embargo.

También puede leer más sobre SOOW VS de profundidad en por eso mismo .

 

Building on what @mayank-shukla wrote (case 2: knowing the index of the item to replace), this could also be written with Array.splice:

const replacement = 'B'; let copy = [...this.state.ids] copy.splice(index, 1, replacement)  this.setState({     ids: copy, }) 

REPL Example

Two things to note, here:

  1. Array.splice is mutative; It will change the array it's operating on, but this is a shallow copy of the array because of the spread operator. More on that below.
  2. You can't directly assign the result of a splice, as the return value of Array.splice is actually the deleted element(s). AKA: Do not assign the result of your slice to the variable you intend to assign to IDs in setState, or you will end up with only the deleted value(s).

To follow up on shallow vs deep copies from item 1, please note that if you are replacing object references (vs string literals in the question), you will need to use something like lodash's cloneDeep.

There are a handful of other ways around this, though.

You can also read more about shallow vs deep on SO itself.

 
 
   
   
0
 
vote
  this.setState({   ids: [ids[1]='B',...ids].slice(1) });   

El código anterior creará dos elementos de matriz de valor 'B',
uno al principio y otro en la posición especificada. Simplemente use el operador de la rebanada para eliminar el primer elemento de matriz.

Otra solución es usar el operador de empalme para hacerlo directamente

  const newIds = this.state.ids.slice() //copy the array newIds[1] = 'B' //execute the manipulations this.setState({ids: newIds}) //set the new state 0  
 
this.setState({   ids: [ids[1]='B',...ids].slice(1) }); 

The above code will create two array items of value 'B' ,
one at the begining and one at the specified position. simply use slice operator to remove the first array element.

Another Solution is to use splice operator to do it directly

this.setState({   ids: [ids.splice(1,1,'B')] }) 
 
 
0
 
vote

Me doy cuenta de que esta pregunta es vieja, pero hoy hay una mejor respuesta.

Immer se puede usar para soportar una forma más sensible de cambiar objetos inmutables, con una API familiar. Al pasar una función a const newIds = this.state.ids.slice() //copy the array newIds[1] = 'B' //execute the manipulations this.setState({ids: newIds}) //set the new state 1111111, puede usarla para transformar su estado.

  const newIds = this.state.ids.slice() //copy the array newIds[1] = 'B' //execute the manipulations this.setState({ids: newIds}) //set the new state 2  

O, si se siente más cómodo con currying, 99887776613 es un atajo útil para crear una función que toma un argumento y lo reenvía en su transformación:

  const newIds = this.state.ids.slice() //copy the array newIds[1] = 'B' //execute the manipulations this.setState({ids: newIds}) //set the new state 4  

He llegado a encontrar que cuando los cambios de estado profundo están involucrados, Immer es genial, pero se advierte que no viene de forma gratuita.

 

I realize this question is old but today there's a better answer.

immer can be used to support a more sensible way to change immutable objects, with a familiar API. By passing a function to this.setState, you can use it to transform your state.

this.setState(state => produce(state, state => {   state.ids[1] = 'b' })); 

Or, if you're more comfortable with currying, produce(fn) is a helpful shortcut to create a function that takes an argument and forwards it into your transformation:

this.setState(produce(state => {   state.ids[1] = 'b' })); 

I've come to find that when deep state changes are involved Immer is great, but be warned that it doesn't come for free.

 
 

Relacionados problema

2  Configuración de reaccionar StyleGuidist con Siguiente.js y TypeScript  ( Setting up react styleguidist with next js and typescript ) 
Estoy tratando de configurar reaccionar StyleGuidist con Siguiente.js y TypeScript, pero sigo caminando en problemas. My actualyguide.config.js se ve así: ...

1  ¿Cómo puedo poner un formulario de reactjs-bootstrap y la etiqueta H1 lado a lado  ( How can i put a reactjs bootstrap form and h1 tag side by side ) 
Quiero colocar mi grupo de formulario y mi etiqueta H1 lado a lado horizontalmente. He intentado usar la pantalla: bloque en línea y otras cosas, pero sin sue...

0  Haga un bucle para mostrar el objeto de datos de la API en Render usando gráficos reaccsjs  ( Make a for loop to show data object from api in render using charts reactjs ) 
Necesito mostrar algunos datos de la API en el gráfico reaccionar ( https : //canvasjs.com/react-charts/chart-index-data-label/ ) Esta es mi API en frente: ...

0  La función de despacho simulada no se llama  ( Mock dispatch function is not called ) 
Estoy escribiendo una prueba para el creador de acción de ASYNC, pero encontró un problema donde se declara "Función de simulacros esperada para que se haya ...

84  Los manipuladores de eventos en reaccionan componentes sin estado  ( Event handlers in react stateless components ) 
Tratando de averiguar una forma óptima de crear manipuladores de eventos en reaccionar componentes sin estado. Podría hacer algo así: const myComponent = (...

1  ¿Cómo agregar a una aplicación de reacción usando Vanilla Javascript?  ( How to append to a react app dom using vanilla javascript ) 
Estoy creando una extensión de cromo que me permite resaltar texto desde cualquier sitio web. solo para darte una idea public String showCourse(Course c)...

0  Integración de la solicitud de Axios basada en clase al código basado en gancho  ( Integrating class based axios request to the hook based code ) 
¿Cómo puedo integrar esta solicitud de Axios basada en clase al otro código basado en gancho que obtiene datos de un archivo JSON? Básicamente, quiero reempla...

0  Reacciona URL de panel compartable  ( React sharable panel url ) 
Considerar mi siguiente fragmento. En este momento, haga clic en el botón, se abre un DIV-THE que carga otro componente. La URL es simplemente ' http: /// loc...

0  Cómo enviar un formulario en reaccionar  ( How to submit a form in react ) 
Quiero saber si es posible enviar un formulario que no está en el componente reaccionar por Fetch en el componente de reacción. <form action="json.bc" clas...

0  Reaccionar - ¡Niños que acceden a los padres estado demasiado pronto?  ( React children accessing parents state too early ) 
Cuando utilice una devolución de llamada de un niño a App.js, la función de devolución de llamada en App.js establece el estado de un elemento. En la misma fu...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos