简体   繁体   中英

CSS changes on new line in react component

I have a react component that contains inline-block div items each with a border right to provide a 'divider' visual. However, if it reaches the max width of the parent component, whether through initial loading or further resizing of the window, the last item of that line should not have a border right. It should look something like this:

Item 1 | Item 2 | Item 3 | Item 4

Item 5 | Item 6 | Item 7

I've read about using jquery to detect when an item has a change of offsetTop value but I'm not sure how it will interact with a react component. Any guidance is appreciated.

You can use css:

:nth-last-child {
    border-right-style: none;
}

Well, the trick here is to use ref to get left offset of the item, if the left offset of the item is 0 then add leftmost class to it. The calculation is done after component has been mounted (in componentDidMount method).

And also, I add version props that is incremented on every window resize (debounced to avoid excessive update, you can lower the timeout or remove it altogether if you want) to force recalculation of the state of the border when browser window is resized.

Make sure to run the demo at full page mode to see what happen when browser window is resized.

 class Item extends React.Component { constructor(props){ super(props); this.state = { isLeftMost: false }; this.recalculateBorder = () => { if(this.el){ this.setState({isLeftMost: this.el.offsetLeft === 0}); } } } componentDidMount(){ this.recalculateBorder(); } componentDidUpdate(){ this.recalculateBorder(); } shouldComponentUpdate(nextProps, nextState){ return (nextProps.label !== this.props.label) || (nextProps.version !== this.props.version) || (nextState.isLeftMost !== this.state.isLeftMost); } render(){ let cl = this.state.isLeftMost ? "item leftmost" : "item"; return ( <div className={cl} ref={el => this.el = el}>{this.props.label}</div> ); } } class Container extends React.Component { constructor(props){ super(props); this.state = { version: 0 }; let _updateDimensions = () => { this.setState({version: this.state.version+1 }); } this.updateDimensions = _.debounce(_updateDimensions, 25); } componentDidMount() { window.addEventListener("resize", this.updateDimensions); } componentWillUnmount() { window.removeEventListener("resize", this.updateDimensions); } render(){ let items = []; for(let i = 0; i<30; i++){ items.push(<Item key={i} label={"item " + i} version={this.state.version} />); } return ( <div className="container"> {items} </div> ); } } ReactDOM.render(<Container />, document.getElementById("root")); 
 .container { position: relative; } .item { display: inline-block; padding: 0 5px; border-left: solid 2px red; } .item.leftmost { border-left-color: transparent; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> <div id="root"></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM