DEV Community

loading...

Discussion on: In React, component controls you!

Collapse
pengeszikra profile image
Peter Vivo

Maybe without DOM manipulation can solve this problem lot easier:

import React, { useState } from 'react';

const changeHandler = setter => ({target:{value}}) => setter(value);

export default () => {
  const [counter, setCounter] = useState(0);

  return (
    <pre>
      <input value = {counter} onChange={changeHandler(setCounter)}/>
      <button onClick={ _ => setCounter(v => +v ? +v + 1 : 1)}> + </button>
      <button onClick={ _ => setCounter(v => +v ? +v - 1 : -1)}> - </button>
    </pre>
  );
}
Enter fullscreen mode Exit fullscreen mode

when need lot of counters we can give value / set function (action) to each one:

import React, { useState } from 'react';

const changeHandler = setter => ({target:{value}}) => setter(_ => value);

const InputCounter = ({counter, setCounter}) => (
  <div>
    <input value = {counter} onChange={changeHandler(setCounter)}/>
    <button onClick={ _ => setCounter(v => +v ? +v + 1 :  1)}> + </button>
    <button onClick={ _ => setCounter(v => +v ? +v - 1 : -1)}> - </button>
  </div>
);

export default () => {
  const [counterList, setCounterList] = useState([1,2,3,4,'wrong starting value',7,'1e10','0xfdf']);

  const setIndexed = index => setter => setCounterList(
    list => list.map(
      (v, i) => i === index
        ? setter(v)
        : v
    )
  );

  return (
    <pre>
      {counterList.map(
        (counter, index) => (
          <InputCounter 
            counter={counter}
            key={index}
            setCounter={setIndexed(index)}
          />
        )
      )}
      {JSON.stringify(counterList ,null , 2)}
    </pre>
  )
}
Enter fullscreen mode Exit fullscreen mode

bonus: works with hexadecimal values written 0xABC format