repository: bigsaigon333/react-payments
form elements: <input>, <textarea>, <select> ...
form elements의 자체 상태에 대한 제어권을 누가 가지고 있느냐에 따라 나뉜다.
const Input = () => {
const [value, setValue] = useState("");
const handleChange = (event) => {
setValue(event.target.value);
}
return <input type="text" value={value} onChange={handleChange}/>
}
const Form = () => {
const ref = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
console.log(ref.current.value);
}
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={ref}/>
</form>
);
}
https://reactjs.org/docs/forms.html
https://reactjs.org/docs/uncontrolled-components.html
https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
ref는 DOM 노드 또는 React Elements(instance)에 접근하기 위하여 React에서 제공하는 방법입니다.
일반적인 React dataflow에서 부모 컴포넌트는 props를 통해서만 자식과 상호작용한다. 자식을 변경하기 위해서는 새로운 props를 넘겨주는 방식입니다. 이러한 전형적인 dataflow가 아닌 특별한 경우에 명령적으로 자식을 변경할 수 있는 수단으로서 React는 ref를 제공한다.
ref는 React.createRef 로 생성하여 ref attribute에 넘겨준다. 그러면 리액트 노드에 대한 레퍼런스는 ref.current 로 접근가능합니다. 리액트 노드가 HTML Element인 경우, 이는 DOM 객체입니다. 클래스 컴포넌트인 경우, 마운트 된 클래스 컴포넌트의 인스턴스입니다. 함수 컴포넌트의 경우에는, 인스턴스가 없으므로 ref attribute를 사용할 수 없습니다. → forwardRef (HOC) 필요
다만, 함수 컴포넌트 내에서 다른 HTML Element 또는 클래스 컴포넌트에 ref를 사용할 수는 있습니다.
React.forwardRef accepts a rendering function as an argument. React will call this function with props and ref as two arguments. This function should return a React node.
props를 넘겨서 할 수 있다면, ref를 사용하지 말라. 그럼에도 ref를 사용해야 다는 생각이 들면 상태 끌어올리기를 통해서 상태를 더 높은 계층에 둔다면 해결될 수도 있다.
this.inputRef = React.createRef();
const refContainer = useRef(initialValue);
createRef는 매 render시에 새로운 ref를 반환하는 반면, useRef는 매번 같은 ref를 반환합니다.
클래스 컴포넌트에서는 constructor 에서 createRef를 통해 ref를 생성하면 컴포넌트의 생애주기와 ref의 생애주기가 일치하지만, 함수 컴포넌트는 인스턴스화 되지 않고 한 번 실행후 값을 반환하고 종료되므로, 함수 컴포넌트에서 craeteRef를 계속 실행하면 새로운 ref 객체를 계속 생성하게 됩니다. 이는 불필요한
useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.
This works because useRef() creates a plain JavaScript object. The only difference between useRef() and creating a {current: ...} object yourself is that useRef will give you the same ref object on every render.
Well, the difference is that createRef will return a new ref on every render while useRef will return the same ref each time.
instance가 없는 함수 컴포넌트에서 useRef는 값을 persist 하는 용도로도 활용될 수 있다. useState hook은 re-render를 trigger하지만, 그럴 필요가 없는 값들은 useRef에 넣을 수 있다.
const usePrevious = (value) => {
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
};
https://reactjs.org/docs/refs-and-the-dom.html
https://reactjs.org/docs/forwarding-refs.html
https://reactjs.org/docs/react-api.html#reactforwardref
https://reactjs.org/docs/hooks-reference.html#useref
https://stackoverflow.com/questions/54620698/whats-the-difference-between-useref-and-createref
https://woowacourse.github.io/javable/post/2021-05-15-react-ref/