最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Rendering Different Components - Stack Overflow

programmeradmin1浏览0评论

Let's say I'm building a react application that changes content inside a box with a button click in this manner(Clicking the same button):

Click 1: Component 1
Click 2: Component 2
Click 3: Component 3
Click 4: Component 1
Click 5: Component 2
Click 6: Component 3

So the obvious way to do this would be via states, and in the render method render the ponent you wish according to what the state is. But I don't wish to rerender every ponent. That is, on the button click, I just want the previous ponent to bee invisible, and display the new element.

This is easy to do in simple normal HTML/CSS/JS:

display:none;

But how would one approach this in react, and why would it be better/more efficient than just doing it normally?

Not necessarily looking for full code, more of an understanding of what to do.

Thanks in advance!

Let's say I'm building a react application that changes content inside a box with a button click in this manner(Clicking the same button):

Click 1: Component 1
Click 2: Component 2
Click 3: Component 3
Click 4: Component 1
Click 5: Component 2
Click 6: Component 3

So the obvious way to do this would be via states, and in the render method render the ponent you wish according to what the state is. But I don't wish to rerender every ponent. That is, on the button click, I just want the previous ponent to bee invisible, and display the new element.

This is easy to do in simple normal HTML/CSS/JS:

display:none;

But how would one approach this in react, and why would it be better/more efficient than just doing it normally?

Not necessarily looking for full code, more of an understanding of what to do.

Thanks in advance!

Share Improve this question edited May 31, 2017 at 5:56 idude asked May 31, 2017 at 5:50 idudeidude 4,9428 gold badges38 silver badges51 bronze badges 5
  • click 2 means click of button 2 or twice click on same button ? – Mayank Shukla Commented May 31, 2017 at 5:54
  • @MayankShukla Twice click of the same button. There is only button, sorry for the confusion. I'll edit the question. – idude Commented May 31, 2017 at 5:56
  • 1 Maintain a counter as an state and increment it on every click, based on that router you can conditionally add styles to your ponent eg onClick={() => {this.setState((prevState) => ({counter: (prevState.counter + 1)%3)}))}} and then in the ponent style which you need to apply internally on ponent outermost div <Component1 style={(this.state.counter == 0)? {display: 'block'}: {display: 'none'}}/> – Shubham Khatri Commented May 31, 2017 at 6:01
  • @ShubhamKhatri But why should I use React for this, does doing this with react make the operation more efficient? Also, if you wish, you can also put your ment as an answer. Thanks! – idude Commented May 31, 2017 at 6:03
  • What I would do generally is not have all the ponents loaded and hide them but render them conditionally and yes I will add it as an answer – Shubham Khatri Commented May 31, 2017 at 6:07
Add a ment  | 

4 Answers 4

Reset to default 2

Maintain a counter as an state and increment it on every click, based on that value you can conditionally add styles to your ponent eg

 onClick={() => {
     this.setState((prevState) => (
            {counter: (prevState.counter + 1)%3)}
             )
    )}
 } 

and then in the ponent style which you need to apply internally on ponent outermost div

<Component1 style={(this.state.counter == 0)? {display: 'block'}: {display: 'none'}}/>

And in Component1

render() {
    return <div style={this.props.style}>{/* Content Here */}</div>
}

Also since React maintains a Virtual DOM for updates, it is more efficeint and fast in rendering contents

Hope this helps. Let me know if you need any explanations...

class Container extends React.Component {
  constructor(props) {
    super(props);
  }
  
  getContainer() {
    switch (this.props.id) {
      case 1:
        return (<div>First Container</div>);
      case 2:
        return (<div>Second Container</div>);
      case 3:
        return (<div>Third Container</div>);
      case 4:
        return (<div>4th Container</div>);
      case 5:
        return (<div>5th Container</div>);
      case 6:
        return (<div>6th Container</div>);
      case 7:
        return (<div>7th Container</div>);
      case 8:
        return (<div>8th Container</div>);
      default:
        return (<div>don't have a Container</div>);
    }
  }
  
  render() {
    return (
      <div>
        {this.getContainer()}
      </div>
      );
  }
};

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 1
    };
    this.test = this.test.bind(this);
  }
  
  test() {
    this.setState(prevState => ({
      count: this.state.count + 1
    }));
  }
  
  render() {
    return (
      <div>
        <button onClick={this.test}> click me {this.state.count}</button>
        <Container id={this.state.count}/>
      </div>
    );
  }
}

ReactDOM.render( <
  Test / > ,
  document.getElementById('main')
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="main"></div>

Use state and cycle a counter between 1 and 6 and use a counter as you're imagining. Simple logic in the render function, or a subsequent sub-ponent can map to the 6 display ponents you want to show.

Since react diffs their shadow DOM to minimizes changes on re-render, you'll typically save a good deal of render overhead while creating more expressive code pared to changing HTML tag displays or classes.

Looking at the bigger picture, I'd say put it together in React using the design patterns you see in the documentation and don't worry about further optimization unless/until you run into a problem. Usually your render bottleneck will be a badly written recurring function, not React's re-rendering of ponents.

Edit:

I'd like to add that you can still target HTML elements by the available HTML/CSS/JS attributes by adding onClick attributes to your React render elements that call a function defined in the React class. In this way, you could still change your display or class attributes while keeping the other benefits of the React library and general design pattern. I've used this to start autofocus on a ponent or other functions in the past. In the case of rendering a ponent, I still suggest you trust React's optimizations unless/until the give you a reason not to.

You won't be able to acplish this in React without managing state and rerendering. If you wanted to render all but one of the slides with display: none you'd have to manage state somewhere, and rerender the ponent with the new style when it changes.

A central part of React's paradigm is its declarative approach. This means that ponents, with the same properties and state, will always render the same view. What you are asking for is

1) a ponent that will render different views for the same props/state

OR

2) access the DOM from inside a React ponent and change the style of an element

Neither approach is viable in React, and by design.

As far as whether or not this makes sense to build in React, there's not a straightforward answer for that. If you're wanting just a static carousel and some other static content, then probably vanilla JS or jQuery are valid options. If you're wanting to build a dynamic carousel that calls a server-side API to populate content from a CMS or trying to build a reusable ponent that can be integrated into various parts of your app, then React is probably the way to go.

发布评论

评论列表(0)

  1. 暂无评论