简体   繁体   中英

React.js - How to implement a function in a child component to unmount another child from the same parent, and mount another component on it's place?

For example, a component like this:

import React, { Component } from 'react';
import BodyContent from './BodyContent';
import BottomOne from './BottomOne';
import BottomTwo from './BottomTwo';
class App extends Component {
  render() {
    return (
      <div className="App">
        <BodyContent />
        <BottomOne />
      </div>
    );
  }
}

export default App;

I want to implement a function on BodyContent that unmount BottomOne and mounts BottomTwo instead, so when I activate the function, the code is reestructured to this:

import React, { Component } from 'react';
import BodyContent from './BodyContent';
import BottomOne from './BottomOne';
import BottomTwo from './BottomTwo';
class App extends Component {
  render() {
    return (
      <div className="App">
        <BodyContent />
        <BottomTwo />
      </div>
    );
  }
}

export default App;

I'm very new to React, so if there's a better way to do it, I'm open to suggestions, but I really need that end result, a function on BodyContent that unmounts BottomOne and mounts BottomTwo .

You can maintain a state which tells which component to render. Something roughly like this

import React, { Component } from 'react';
import BodyContent from './BodyContent';
import BottomOne from './BottomOne';
import BottomTwo from './BottomTwo';
class App extends Component {
  changeBottomComponent = (comp) => {
    this.setState({ showBottom: comp})
  }
  render() {
    return (
      <div className="App">
        <BodyContent changeBottomComponent={this.changeBottomComponent}/>
        {this.state.showBottom === 1 ? <BottomOne /> : <BotttomTwo />}

      </div>
    );
  }
}

export default App;

You can use state or props to render different components.

Example:

import React, {
    Component
}
from 'react';
import BodyContent from './BodyContent';
import BottomOne from './BottomOne';
import BottomTwo from './BottomTwo';
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            decider: false
        };
    }
    render() {
        const bottomContent = this.state.decider === true ? <BottomOne /> : <BottomTwo />;
        return (
            <div className="App">
                <BodyContent />
                { bottomContent }
            </div>
        );
    }
}
export
default App;

To achieve that maintain a state variable in parent component (some kind of identifier for component) and use that state variable to render different component.

Along with that you also need to pass a function from parent to child and use that function to update the parent state value.

Like this:

class App extends Component {
  constructor(){
    super();
    this.state={
      renderOne: true,
    }
    this.update = this.update.bind(this);
  }

  update(){
      this.setState({renderOne: false})
  }

  render() {
    return (
      <div className="App">
        <BodyContent update={this.update}/>
        {this.state.renderOne?  <BottomOne />  : <BottomTwo/> }
      </div>
    );
  }
}

Now inside BodyContent component call this.props.update() to render another component.

You can also directly use the components in the state and render them. Could be more flexible this way.

 const BottomOne = () => <div>BottomOne</div>; const BottomTwo = () => <div>BottomTwo</div>; class Example extends React.Component { constructor() { super(); this.state = { show: BottomOne }; this.toggleComponent = this.toggleComponent.bind(this); } toggleComponent() { // Use whatever logic here to decide. let show = BottomOne; if (this.state.show === BottomOne) { show = BottomTwo; } this.setState({ show }); } render() { return ( <div> <button onClick={this.toggleComponent}>Change</button> <this.state.show /> </div> ); } } ReactDOM.render(<Example />, document.getElementById('root')); 
 <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> <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