Michael Jackson - Never Write Another HoC
Why Stack Overflow recommends it
Stack Overflow users link it when answering questions about alternatives to HOCs, and cite it as the main case for render props and function-as-child components in React.
Recommended by 5 people across 4 different months, 2017 to 2020.
What it is
A 2017 conference-style talk from the Phoenix ReactJS meetup by Michael Jackson, creator of React Router. He argues that a component using a render prop or function-as-children can do everything a higher-order component can, and more.
What people said
Recommends Tiago Engel · 2017-11 · Stack Overflow · on “What are the alternatives for high order component in react?”
There is something called function as child components (not sure if that's an official name but anyways) The basic idea is that react accepts functions as child components, so for example instead of the react redux's connect HOC component you could do something like this <Connect mapStateToProps={myMapper}> {({ users, isLoading })} => { //renders the user }} and the connect implementation is quite simple compared to a HOC. render() { return this.props.children( this.props.mapStateToProps(this.state) ) } You can check a pretty interesting video about it here: [this video]
Recommends Sam H. · 2017-11 · Stack Overflow · on “FP alternative to polymorphism in JavaScript/ReactJS”
If you have a chance, check out this talk from September. MJ make a good point, and my advice now is "always use render props to parametrize React components." [this video]
Recommends tay_thomp · 2018-01 · Stack Overflow · on “ReactJS set state of a component from an other component”
It is indeed possible! One of the nice ways to do this in React is to use render props [this video] . However, for this simple case, you could do something like this: const Block1 = (props) => <div>whatever stuff goes here</div> class Block2 extends React.Component{ constructor(){ super() this.state = { showElem: false } } handleClick() { this.setState({ showElem: !this.state.showElem }) } render() { const { showElem } = this.state return ( <div> <a onClick={this.handleClick.bind(this)}>Click to show Block1</a> { showElem && <Block1 /> } </div> ) } } Essentially, you are rendering the whole Block1 element according to the state of Block2 . If you change showElem to true, Block1 will be rendered,
Recommends jens · 2018-03 · Stack Overflow · on “Updating parent's state from Routed component”
Not a weird approach. Render props is a pattern that is gaining traction in the React community. The withRouter HOC that comes with ReactRouter is implemented using a render prop. Passing props from the parent down is an specific use case that this solves. Here is a video that may convince you [this video]
Recommends EQuimper · 2018-06 · Stack Overflow · on “React Native composite component calling setState of the parent from a child component”
Because I see you have use HOC as the answer, I think can make use of renderProps. This will be better than using HOC. You get more freedom and also you don't gonna have props naming problem. A good video where you can see the strength of it vs HOC [this video] Little example class DocumentScreen extends Component { state = { value: '' } save() { console.log(this.state); } handleChange = value => { this.setState({ value }) } render() { return ( <View> {this.props.children({ handleChange: this.handleChange })} <View> <Button onClick={this.save.bind(this)}/> </View> </View> ); } } const Input = (props) => ( <DocumentScreen {...props}> {({ handleChange }) => ( <View> <TextInput onChangeText={handleC
Cites brietsparks · 2017-11 · Stack Overflow · on “FP alternative to polymorphism in JavaScript/ReactJS”
EDIT: This is post is out of date. Hooks are better for most use cases. Original Answer: The answer regarding your example code is in the middle/bottom of this post. A good way to go about React composition is the render-callback pattern [this video] , aka function-as-child. The main advantage it has over HOC's is that it allows you to compose components dynamically at runtime (e.g. in render) instead of statically at author time. Regardless of whether you use render-callback or HOC's, the goal in component composition is to delegate reusable behavior to other components , and then pass those components in as props to the component that needs them. Abstract example: The following Delegator compon
Cites Bogdan Surai · 2018-02 · Stack Overflow · on “React with Redux: is there a way to sync the "same" components?”
There are two ways: 1st. You can connect both layouts to redux state .... import { connect } from 'react-redux'; const mapStateToProps = (yourGlobalState) => { return ({ data: yourGlobalState.stateOfForm }); }; export const Mobile = connect(mapStateToProps)(MobileLayout); export const Desctop = connect(mapStateToProps)(DesctopLayout); Also you can use decorators @connect(mapStateToProps) export class MobileLayout extends React.Component { .... } 2nd. You can create higher layer to keep state for both layouts. This layer will get the state either by connect (like in 1st way) or from another components. .... export class HigherLayer extends React.Component { render() { const { data, isMobile }
Cites Lev · 2018-03 · Stack Overflow · on “this.props.children({extra: 'things'}) not working”
I would like to pass some state to a component's children like this (example seen here [this video] ) const WithExtraThings = ({ children }) => children({extra: 'things'}) The pattern above isn't working so I am doing this const WithExtraThings = ({ children }) => {React.Children.map(children, child => React.cloneElement(child, { extra: 'things' })} Can you confirm that the first example is outdated ?
Cites Matt Carlotta · 2020-01 · Stack Overflow · on “How can I include URL params when programmatically navigating using the history API (not Links)?”
I'm not 100% sure I understand your intent, but perhaps this might work... where it allows you to add/remove queries manually via user interactions and/or by navigating through browser history (mouse back and forward). It'll also persist queries across page refreshes. If you absolutely need to use a params option, then I'd place it within the Route's path and access it via (this.props.)location.params . If it needs to be dynamically replaced, then you're better off moving it within the query params like so: /movies/action?subcategory=comedy&year=2019&starring=Bob%20Saget . When you start swapping out params, then your Route structure can become unnecessarily cluttered and harder to manage. N
Cites Matt Carlotta · 2020-02 · Stack Overflow · on “Refactoring and Cleaning Up Code in React - Dealing with Conditions and Wrapper Components”
I'd recommending hoisting the Track and ProductLink into a reusable component -- that way you'll simplify it to one condition. For example: import React from "react"; import PropTypes from "prop-types"; import Track from "./path/to/Track"; import ProductLink from "./path/to/ProductLink"; const TrackProduct = ({ children, isTracked }) => ( isTracked ? <Track> <ProductLink> {children} </ProductLink> </Track> : children ); TrackProduct.proptTypes = { children: PropTypes.node.isRequired, isTracked: PropTypes.bool.isRequired }; export default TrackProduct; Then import the above reusable component and control it via state : import React from "react"; import TrackProduct from "./path/to/TrackProduc