Last active
September 1, 2018 22:28
-
-
Save xnimorz/d4044f1c84274a494adfc6d36a916170 to your computer and use it in GitHub Desktop.
WhyObjectRefsAreGood.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With callbacs: | |
class List extends Component { | |
constructor(props) { | |
super(props); | |
props.items.map(item => | |
this.refsCallbacks[item.id] = (el) => this.refs.items[item.id] = el; | |
); | |
// also you can store refCallbacks in state. | |
} | |
componentWillReceiveProps(nextProps) { | |
if (nextProps.items !== this.props.items) { | |
nextProps.items.map(item => { | |
if (this.refsCallbacks[item.id]) { | |
return; | |
} | |
this.refsCallbacks[item.id] = (el) => this.refs.items[item.id] = el; | |
}); | |
} | |
} | |
componentDidMount() { | |
this.calculate(); | |
} | |
componentDidUpdate() { | |
this.calculate(); | |
} | |
refsCallbacks = {}; | |
refs = {items: {}}; | |
calculate() { | |
// Calculate width of elements and hide elements that overflow container | |
this.refs.items.map(...); // Good | |
} | |
render() { | |
const { items } = this.props; | |
return ( | |
<div className='container'> | |
{items.map(item => | |
<div | |
ref={this.refCallbacks[item.id]} | |
key={item.id} | |
className='item' | |
> | |
{item.content} | |
</div> | |
)} | |
</div> | |
); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With callbacs: | |
class List extends Component { | |
receiveRef = (el) => { | |
this.refs.items[el.dataset.id] = el; | |
} | |
componentDidMount() { | |
this.calculate(); | |
} | |
componentDidUpdate() { | |
this.calculate(); | |
} | |
refsCallbacks = {}; | |
refs = {items: {}}; | |
calculate() { | |
// Calculate width of elements and hide elements that overflow container | |
this.refs.items.map(...); // Good | |
} | |
render() { | |
const { items } = this.props; | |
return ( | |
<div className='container'> | |
{items.map(item => | |
<div | |
ref={this.receiveRef} | |
data-id={item.id} | |
key={item.id} | |
className='item' | |
> | |
{item.content} | |
</div> | |
)} | |
</div> | |
); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With inline callbacks | |
class List extends Component { | |
componentDidMount() { | |
this.calculate(); | |
} | |
componentDidUpdate() { | |
this.calculate(); | |
} | |
refs = {items: {}}; | |
calculate() { | |
// Calculate width of elements and hide elements that overflow container | |
this.refs.items.map(...); // Good | |
} | |
render() { | |
const { items } = this.props; | |
return ( | |
<div className='container'> | |
{items.map(item => | |
<div | |
ref={(el) => this.refs.items[item.id] = el} // There is some specific work after each render https://reactjs.org/docs/refs-and-the-dom.html#caveats | |
// ref={(el) => this.refs.items.push(el)} // bad idea: https://reactjs.org/docs/refs-and-the-dom.html#caveats | |
key={item.id} | |
className='item' | |
> | |
{item.content} | |
</div> | |
)} | |
</div> | |
); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With inline callbacks | |
class List extends Component { | |
constructor() { | |
super(props); | |
// less code than in previous example | |
props.items.map(item => { | |
this.refs.items[item.id] = React.createRef(); | |
}); | |
} | |
componentWillReceiveProps(nextProps) { | |
if (nextProps.items !== this.props.items) { | |
props.items.map(item => { | |
if (this.refs.items[item.id]) { | |
return; | |
} | |
this.refs.items[item.id] = React.createRef(); | |
}); | |
} | |
} | |
componentDidMount() { | |
this.calculate(); | |
} | |
componentDidUpdate() { | |
this.calculate(); | |
} | |
refs = {items: {}}; | |
calculate() { | |
// Calculate width of elements and hide elements that overflow container | |
this.refs.items.map(...); // Good | |
} | |
render() { | |
const { items } = this.props; | |
return ( | |
<div className='container'> | |
{items.map(item => | |
<div | |
ref={this.refs.items[item.id]} | |
key={item.id} | |
className='item' | |
> | |
{item.content} | |
</div> | |
)} | |
</div> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With String refs: | |
class List extends Component { | |
componentDidMount() { | |
this.calculate(); | |
} | |
componentDidUpdate() { | |
this.calculate(); | |
} | |
calculate() { | |
// Calculate width of elements and hide elements that overflow container | |
Object.keys(this.refs).map(...) // Bad practise | |
} | |
render() { | |
const { items } = this.props; | |
return ( | |
<div className='container'> | |
{items.map(item => <div ref={`item-${item.id}`} key={item.id} className='item'>{item.content}</div>)} | |
</div> | |
); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment