简体   繁体   中英

I can't update my string value with React hooks

Its like the simplest of cases you can think of,

I have a select which updates a string according to the value which is supposed to update a property of the select itself (its background color)

I am using React hooks and Styled Components to achieve this.

I have Redux to be able to bind it an immutable array of colors in the future.

The question is simple, why can't I update the state? I have tried to print it and it is always an empty string.

Here is my styles file

let currentColor = '';

const SelectColor = styled.div`
  select{
    background-color: ${currentColor || 'black'};
  }
  .label{
    width: 150px;
    font-size: 14px;
    text-align: left;
    margin-left: 6px;
  }
`;

This is the component that isn't updating the selectValue for reasons I cannot grasp(I have attempted to console log it and it returns always empty string). I have checked the documentation a couple times and it seems like its meant to be updated this way so I am clueless...

const SelectComponent = ({
  disabled,
  colorList,
  label,
  onSelect,
  ...restProps
}) => {
  const [selectValue, setSelectValue] = useState('');

  const handleChange = useCallback(
    (e) => {
      setSelectValue(e.target.value);
      console.log(selectValue);
    },colorList
  );

  return (
    <SelectColor>
      <span className='label'>{label}</span>
      <select onChange={e=>handleChange(e)}>
        {
          colorList.map(color =>
          <option key={color} value={color}>{color}</option>)
        };
      </select>
    </SelectColor>
  );
};

SelectComponent.propTypes = {
  disabled: PropTypes.bool,
  hourValue: PropTypes.number,
  projectName: PropTypes.string,
};


export default SelectComponent;

Your handlechange function is a bit strange to me as the function itself does not take in a variable. try writing it like this

 const handlestring = (e) => {
   setSelectedValue(e.target.value)
}

Here you have some fixes, check the comments in the code:

// SelectComponent
const SelectComponent = ({
  disabled,
  colorList,
  label,
  onSelect,
  ...restProps
}) => {
  const [selectValue, setSelectValue] = useState('');

  // Make this a function, not an arrow function. 
  // It's unnecessary in this case due to not needing a binding
  function handleChange(e) {
    setSelectValue(e.target.value);
  }

  // send currentColor as a prop to your styled component and remove 
  // the arrow onChange, not needed.
  return (
    <SelectColor currentColor={selectValue}>
      <span className='label'>{label}</span>
      <select onChange={handleChange}>
        {
          colorList.map(color =>
          <option key={color} value={color}>{color}</option>)
        };
      </select>
    </SelectColor>
  );
};

SelectComponent.propTypes = {
  disabled: PropTypes.bool,
  hourValue: PropTypes.number,
  projectName: PropTypes.string,
};


export default SelectComponent;
// Your styled components receives now a prop with the name currentColor.
// Use it inside the interpolation string ${} and set the value
const SelectColor = styled.div`
  select{
    background-color: ${(props) => props.currentColor || 'black'};
  }
  .label{
    width: 150px;
    font-size: 14px;
    text-align: left;
    margin-left: 6px;
  }
`;

Hope this helps! Ask whatever you feel necessary, I'll help if I'm available!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM