## Imperative React 🔹 [[❞ React Fundamentals (R2R)|React Fundamentals (R2R)]] 🔸 [[Component Composition]], [[Inline Handlers]], [[⧋ React|React]] ### Imperative React vs Declaritive - What vs How In **declaritive react**, you could simply set the input field’s autofocus attribute: ```js <input id={id} type={type} value={value} autoFocus onChange={onInputChange} /> ``` However, when reusing a component, only the last rendered component would receive the autoFocus on render. Instead, a reuseable React component can pass a dedicated prop and let the developer decide if the input field should have autofocus. ```html <InputWithLabel id=“search” value={searchTerm} isFocused onInputChange={handleSearch}> ``` Within the component, use the new prob for the Input field’s autoFocus attribute. ```js Const inputWithLabel = ({ id, value, type=‘text’, onInputChange, isFocused, children, }) => ( <> <input id={id} type={type} value={value} autoFocus={isFocused} onChange={onInputChange} /> </> ); ``` We’re telling React *what* to do not *how* to do it. --- In **imperative programming**, you're telling a program to change its state. Imperitive programming focuses on how something operates step-by-step, i.e. *commands*, rather than a high level of expected results. React is usually **declaritive** - focusing on what a program should accomplish without specifying all the details. Direct commands vs Big picture expectations. **Imperitive** VS **declaritive**: ```js // imperative JavaScript + DOM API element.addEventListener('click', () => { // do something }); ``` ```js // declarative React const App = () => { const handleClick = () => { // do something }; ``` Examples of **imperitive programming** that React needs to control might be: - Read/Write to the DOM to control an objects dimensions or focus state - Complex animations like transitions - Data-driven animations like those in the [D3 JS Library](https://observablehq.com/@d3/gallery) For instance: Generally, React would give a developer an option for what to do when an input field is focused on by passing an `isFocused` prop to a component attribute. ```js const InputWithLabel = ({ id, value, type = 'text', onInputChange, isFocused, children, }) => ( <> <label htmlFor={id}>{children}</label> &nbsp; <input id={id} type={type} value={value} autoFocus={isFocused} // isFocused is passed to autoFocus onChange={onInputChange} /> </> ) ``` Component has an `isFocused` attribute ```js const App = () => { ... return ( <div> <h1>My Hacker Stories</h1> <InputWithLabel id="search" value={searchTerm} isFocused onInputChange={handleSearch} > <strong>Search:</strong> </InputWithLabel> ... </div> ); }; ``` An **imperitive approach** would target the input field via the DOM API once the component has been rendered. See the order (A, B, C, D) for implementation - create a ref with React's `useRef` Hook. `ref` object is persistent, it's property `current` can be changed. - Input `ref` attribute is passed a changeable property. - `useEffect` will perform the focus operation after the component renders. - Add `useEffect` will only give access to the current property IF the element is in focus and the property exists `isFocused && inputRef.current`. ```js const InputWithLabel = ({ id, value, type = 'text', onInputChange, isFocused, children, }) => { // A -- uses useRef() const inputRef = React.useRef(); // C -- add useEffect Hook React.useEffect(() => { if (isFocused && inputRef.current) { // D -- check current Focus inputRef.current.focus(); } }, [isFocused]); return ( <> <label htmlFor={id}>{children}</label> &nbsp; {/* B */} // add ref attribute to input field <input ref={inputRef} id={id} type={type} value={value} onChange={onInputChange} /> </> ); }; ``` This gives more control to the object since a declarative approach is not always possible, but imperative approach can be performed when necessary. ### References 1. Wieruch, Robin (2019). *Imperative React*. [Road to React](https://courses.robinwieruch.de/p/the-road-to-learn-react)