Warning: You provided a `value` prop to a form field without an `onChange` handler

Как исправить Warning: You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or `readOnly ?

import React, { useRef, useState, useEffect } from "react";

const quickAndDirtyStyle = {
  width: "200px",
  height: "200px",
  background: "#FF9900",
  color: "#FFFFFF",
  display: "flex",
  justifyContent: "center",
  alignItems: "center"
};

const Container = {
  fontFamily: "sans-serif",
  textAlign: "center",
};

const inputC = {
  width: "100px",
  height: "30px",
  fontSize: "4vw",
  position: "relative",
  top: "0",
  left: "0",
  display: "flex",
  cursor: "pointer"
};

const h1 = {
  display: "block",
  margin: "0",
  padding: "0",
  marginLeft: "20px",
  paddingRight: "10px"
};

export default function App() {

  const [pressed, setPressed] = useState(false);
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const ref = useRef();

  // Monitor changes to position state and update DOM
  useEffect(() => {
    if (ref.current) {
      ref.current.style.marginLeft = `${position.x}px`;
      ref.current.style.marginTop = `${position.y}px`;
    }
  }, [position]);

  // Update the current position if mouse is down
  const onMouseMove = (event) => {
    if (pressed) {
      setPosition({
        x: position.x + event.movementX,
        y: position.y + event.movementY
      });
    }
  };

  return (
    <div className="App" style={Container}>
      <div style={{ display: "flex" }}>
        <h1 style={h1}>X</h1>
        <input className="inputC" style={inputC}  type="number" value={position.x} />
        <h1 style={h1}>Y</h1> 
        <input className="inputC" style={inputC}  type="number" value={position.y} />
      </div>
      <div
        style={{
          position: "absolute",
          top: "50%",
          left: "50%",
          transform: "translate(-50%,-50%)"
        }}
      >
        <div
          ref={ref}
          style={quickAndDirtyStyle}
          onMouseMove={onMouseMove}
          onMouseDown={() => setPressed(true)}
          onMouseUp={() => setPressed(false)}
          onMouseLeave={() => setPressed(false)}
        >
        </div>
      </div>
    </div>
  );
}

Ответы (1 шт):

Автор решения: Nikita Galadiy

Ваш state должен контролироваться самими input. Необходимо добавить для него событие onChange и в обработчике менять значение position

Контролируемые компоненты

const handleChange = (e, type) => {
  setPosition({
    [type]: e.target.value
  });
};

// ...

<input 
  className="inputC" 
  style={inputC}  
  type="number" 
  value={position.x} 
  onChange={(e) => handleChange(e, 'x')} 
/>
<input 
  className="inputC" 
  style={inputC}  
  type="number" 
  value={position.y} 
  onChange={(e) => handleChange(e, 'y')} 
/>
→ Ссылка