## 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>
<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>
{/* 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)