Skip to content
Advertisement

React Redux – Cannot set properties of undefined (setting ‘value’)

I need to find a way to get my data from my redux store into a map function but i end up with the error below

My console gives me for

setVariants(editProduct?.variants?.map((variant) => variant));

this:

[
0:{label: 'Small', price: '5', value: 0}
1: {label: 'Medium', price: '7.5', value: 1}
2: {label: 'Large', price: '10', value: 2}
]

But this code ends to be undefined

  const [variants, setVariants] = useState([
    { label: '', price: '', value: '' },
  ]);

  useEffect(() => {
    setVariants(editProduct?.variants?.map((variant) => variant));
  }, []);

  console.log(variants);

Thats why the code below ends to be: Uncaught TypeError: Cannot set properties of undefined (setting ‘value’)

 {variants.map((variant, index) => (
                      <div key={index} className=' mb-4'>
                        <div className='hidden'>{(variant.value = index)}</div>
                        <div>
                          <label className='block font-bold uppercase mb-2'>
                            <div className='flex'>
                              <div className='mr-2'>Variante {index + 1}</div>
                              <div className='flex justify-center items-center'>
                                <svg
                                  onClick={() => handleAddVariants()}
                                  xmlns='http://www.w3.org/2000/svg'
                                  class='h-5 w-5'
                                  viewBox='0 0 20 20'
                                  fill='currentColor'
                                >
                                  <path
                                    fill-rule='evenodd'
                                    d='M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z'
                                    clip-rule='evenodd'
                                  />
                                </svg>
                                <svg
                                  onClick={() => handleRemoveVariants(index)}
                                  xmlns='http://www.w3.org/2000/svg'
                                  class='h-5 w-5'
                                  viewBox='0 0 20 20'
                                  fill='currentColor'
                                >
                                  <path
                                    fill-rule='evenodd'
                                    d='M10 18a8 8 0 100-16 8 8 0 000 16zM7 9a1 1 0 000 2h6a1 1 0 100-2H7z'
                                    clip-rule='evenodd'
                                  />
                                </svg>
                              </div>
                            </div>
                            <div className='flex'>
                              <input
                                className='mr-4 p-2 h-8 w-36 focus:outline-none bg-gray-700 border-b-2 border-yellow-500 font-semibold'
                                type='text'
                                name='label'
                                placeholder={'Name Variante ' + (index + 1)}
                                value={variant.label}
                                onChange={(event) =>
                                  handleVariantsChangeInput(index, event)
                                }
                              />

                              <input
                                className='h-8 w-16 p-2 focus:outline-none bg-gray-700 border-b-2 border-yellow-500 font-semibold'
                                type='number'
                                step='.01'
                                min='0'
                                name='price'
                                placeholder={'Preis ' + (index + 1)}
                                value={variant.price}
                                onChange={(event) =>
                                  handleVariantsChangeInput(index, event)
                                }
                              />
                              <div className='mt-1 font-semibold'>€</div>
                            </div>
                          </label>
                        </div>
                      </div>
                    ))}

Edit

const initialVariants = [{ label: '', price: '', value: '' }];

const EditProduct = () => {...}
  const [variants, setVariants] = useState(initialVariants);

  console.log(variants);
  console.log(initialVariants);

  useEffect(() => {
    setVariants(
      editProduct?.variants?.map(
        (variant, value) =>
          ({
            ...variant,
            value,
          } ?? initialVariants)
      )
    );
  }, [editProduct]); // don't forget dependencies

Advertisement

Answer

<div className='hidden'>{(variant.value = index)}</div>

I have no idea what this is supposed to be doing but if you wanted to assign a value property from the index position, you should do that when you set the state value.

You should also provide a fallback value in case your optional chaining returns undefined

const initialVariants = [{ label: "", price: "", value: "" }];
const [variants, setVariants] = useState(initialVariants);

useEffect(() => {
  setVariants(
    editProduct?.variants?.map((variant, value) => ({
      ...variant,
      value,
    })) ?? initialVariants
  );
}, [editProduct]); // don't forget dependencies

You can display the value (index) in your render without assigning

{
  variants.map((variant) => (
    <div key={variant.value} className="mb-4">
      <div className="hidden">{variant.value}</div>
      {/* ... etc ... */}
    </div>
  ));
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement