|
266 | 266 | |250| [What is code-splitting?](#what-is-code-splitting)| |
267 | 267 | |251| [What is the benefit of strict mode?](#what-is-the-benefit-of-strict-mode)| |
268 | 268 | |252| [What are Keyed Fragments?](#what-are-keyed-fragments)| |
| 269 | +|253| [Is it React support all HTML attributes?](#is-it-react-support-all-html-attributes)| |
| 270 | +|254| [What are the limitations with HOCs?](#what-are-the-limitations-with-hocs)| |
| 271 | +|255| [How to debug forwardRefs in DevTools?](#how-to-debug-forwardrefs-in-devtools)| |
269 | 272 |
|
270 | 273 | ## Core React |
271 | 274 |
|
|
4213 | 4216 | ); |
4214 | 4217 | } |
4215 | 4218 | ``` |
4216 | | - **Note:** key is the only attribute that can be passed to Fragment. In the future, there might be a support for additional attributes, such as event handlers. |
| 4219 | + **Note:** key is the only attribute that can be passed to Fragment. In the future, there might be a support for additional attributes, such as event handlers. |
| 4220 | +253. ### Is it React support all HTML attributes? |
| 4221 | + As of React 16, both standard or custom DOM attributes are fully supported. Since React components often take both custom and DOM-related props, React uses the camelCase convention just like the DOM APIs. Let us take few props with respect to standard HTML attributes, |
| 4222 | + ```javascript |
| 4223 | + <div tabIndex="-1" /> // Just like node.tabIndex DOM API |
| 4224 | + <div className="Button" /> // Just like node.className DOM API |
| 4225 | + <input readOnly={true} /> // Just like node.readOnly DOM API |
| 4226 | + ``` |
| 4227 | + These props work similarly to the corresponding HTML attributes, with the exception of the special cases. It also support all SVG attributes. |
| 4228 | +254. ### What are the limitations with HOCs? |
| 4229 | +
|
| 4230 | + Higher-order components come with a few caveats apart from its benefits. Below are the few listed in an order |
| 4231 | + 1. **Don’t Use HOCs Inside the render Method:** |
| 4232 | + It is not recommended to apply a HOC to a component within the render method of a component. |
| 4233 | + ```javascript |
| 4234 | + render() { |
| 4235 | + // A new version of EnhancedComponent is created on every render |
| 4236 | + // EnhancedComponent1 !== EnhancedComponent2 |
| 4237 | + const EnhancedComponent = enhance(MyComponent); |
| 4238 | + // That causes the entire subtree to unmount/remount each time! |
| 4239 | + return <EnhancedComponent />; |
| 4240 | + } |
| 4241 | + ``` |
| 4242 | + The above code impact performance by remounting a component that causes the state of that component and all of its children to be lost. Instead, apply HOCs outside the component definition so that the resulting component is created only once |
| 4243 | + 2. **Static Methods Must Be Copied Over:** |
| 4244 | + When you apply a HOC to a component the new component does not have any of the static methods of the original component |
| 4245 | + ```javascript |
| 4246 | + // Define a static method |
| 4247 | + WrappedComponent.staticMethod = function() {/*...*/} |
| 4248 | + // Now apply a HOC |
| 4249 | + const EnhancedComponent = enhance(WrappedComponent); |
| 4250 | + |
| 4251 | + // The enhanced component has no static method |
| 4252 | + typeof EnhancedComponent.staticMethod === 'undefined' // true |
| 4253 | + ``` |
| 4254 | + You can overcome this by copying the methods onto the container before returning it |
| 4255 | + ```javascript |
| 4256 | + function enhance(WrappedComponent) { |
| 4257 | + class Enhance extends React.Component {/*...*/} |
| 4258 | + // Must know exactly which method(s) to copy :( |
| 4259 | + Enhance.staticMethod = WrappedComponent.staticMethod; |
| 4260 | + return Enhance; |
| 4261 | + } |
| 4262 | + ``` |
| 4263 | + 3. **Refs Aren’t Passed Through:** |
| 4264 | + For HOCs you need to pass through all props to the wrapped component but this does not work for refs. This is because ref is not really a prop similar to key. In this case you need to use the React.forwardRef API |
| 4265 | +255. ### How to debug forwardRefs in DevTools? |
| 4266 | +
|
| 4267 | + **React.forwardRef** accepts a render function as parameter and DevTools uses this function to determine what to display for the ref forwarding component. For example, If you don't name the render function or not using displayName property then it will appear as ”ForwardRef” in the DevTools, |
| 4268 | + ```javascript |
| 4269 | + const WrappedComponent = React.forwardRef((props, ref) => { |
| 4270 | + return <LogProps {...props} forwardedRef={ref} />; |
| 4271 | + }); |
| 4272 | + ``` |
| 4273 | + But If you name the render function then it will appear as **”ForwardRef(myFunction)”** |
| 4274 | + ```javascript |
| 4275 | + const WrappedComponent = React.forwardRef( |
| 4276 | + function myFunction(props, ref) { |
| 4277 | + return <LogProps {...props} forwardedRef={ref} />; |
| 4278 | + } |
| 4279 | + ); |
| 4280 | + ``` |
| 4281 | + As an alternative, You can also set displayName property for forwardRef function, |
| 4282 | + ```javascript |
| 4283 | + function logProps(Component) { |
| 4284 | + class LogProps extends React.Component { |
| 4285 | + // ... |
| 4286 | + } |
| 4287 | + |
| 4288 | + function forwardRef(props, ref) { |
| 4289 | + return <LogProps {...props} forwardedRef={ref} />; |
| 4290 | + } |
| 4291 | + |
| 4292 | + // Give this component a more helpful display name in DevTools. |
| 4293 | + // e.g. "ForwardRef(logProps(MyComponent))" |
| 4294 | + const name = Component.displayName || Component.name; |
| 4295 | + forwardRef.displayName = `logProps(${name})`; |
| 4296 | + |
| 4297 | + return React.forwardRef(forwardRef); |
| 4298 | + } |
| 4299 | + ``` |
0 commit comments