在组件之间传递道具或数据React

时间:2019-10-05 13:24:53

标签: javascript reactjs

朋友下午好, 我的页面和组件安排在应用程序的主类中,我可以将某些结果从任何组件或页面传递到主类,并将此属性从主类传递到任何其他组件。 为了很好地描述问题,我将举一个例子:

这是我的主类App.js

import React, {Component} from 'react';
import { BrowserRouter as Router, Route} from "react-router-dom";
import HomePage from "./Pages/HomePage";
import NavBar from "./Components/NavBar";
import PaymentStatus from "./Pages/PaymentStatus";


class App extends Component {

constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {};
};

    render() {
        return (
            <Router>
                <NavBar/>
                <Route name={'Home'} exact path={'/'} component={HomePage}/>
                <Route name={'PaymentStatus'} exact path={'/payment-status/:tId'} component={PaymentStatus}/>
            </Router>
        );
    }
}

export default App;

现在,我的导航栏组件是: NavBar.js

import React, {Component} from 'react';

class NavBar extends Component {

constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {};
};

_makeSomething =async() => {
  // Somw function that returns something
}
render() {
    return (
        <div>
            <div id={"myNavbar"}>
                <div>
                    <a onClick={()=>{this._makeSomething()}} href={'/'}/> Home</a>
                    <a onClick={()=>{this._makeSomething()}} href={"/payment-status"} />Payment Status</a>
            </div>
        </div>
    );
  }
}

export default NavBar;

HomePage.js

import React, {Component} from 'react';

class HomePage extends Component {

constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {};
};

async componentDidMount() {
 console.log(this.props.match.params.tId)
};

render() {
    return (
        <div>
            <div id={"main"}>
                <div>
                    <p>This is home page</p>
            </div>
        </div>
    );
  }
}

export default HomePage;

PaymentStatusPage.js

import React, {Component} from 'react';

class PaymentStatusPage extends Component {

constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {};
};

async componentDidMount() {
 console.log(this.props.match.params.tId)
};

render() {
    return (
        <div>
            <div id={"status"}>
                <div>
                    <p>This is payment Status Page</p>
            </div>
        </div>
    );
  }
}

export default PaymentStatusPage;

现在这是一个问题: 我可以在 HomePage.js PaymentStatusPage.js 中进行某些更改时传递给 App.js 事件(或道具) NavBar.js 另外,想要将接收到的peprops传递给任何组件。 谢谢。

3 个答案:

答案 0 :(得分:1)

您可以在App类中对方法进行decalare,然后通过prop将其传递给另一个组件。 例如 然后,您可以在MyComponent中调用此方法,并将一些值传递给它。这是将值从子组件传递到父组件的方法。在App中的方法中,您可以简单地使用setState。 剩下要做的就是通过prop将这个新的state属性传递给另一个组件。 要在组件使用过程中传递价值,必须改变

<Route component={SomeComponent}

收件人

<Route render={() => <SomeComponent somethingChanged={this.somethingChangedMethodInAppClass}}/>

希望有帮助!

编辑:您还可以使用Redux将状态外部化并在子组件中重用

答案 1 :(得分:1)

您在这里有两个选择:

  • 将所有状态保留在父组件中,,然后将应用程序传递给子组件,甚至可以更新父状态的动作。如果另一个孩子使用该状态,则该孩子也将被重新呈现。

    • 使用 Redux 管理您的状态,并使状态可用于所有组件。

我根据您的情况创建了一个小示例。

在此示例中,App组件的状态为一个名为title的属性,该函数通过props向下传递到Navbar

class App extends Component {
  constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {
      title: "Home Page"
    };
  }

  _makeSomething = title => {
    this.setState({ title: title });
  };

  render() {
    return (
      <Router>
        <NavBar clicked={this._makeSomething} />
        <Route
          name={"Home"}
          exact
          path={"/"}
          component={() => <HomePage title={this.state.title} />}
        />
        <Route
          name={"PaymentStatus"}
          exact
          path={"/payment-status/:tId"}
          component={() => <PaymentStatus title={this.state.title} />}
        />
      </Router>
    );
  }
}

组件HomePagePaymentStatus将以App的状态作为标题,而NavBar将获得_makeSomething的属性。到目前为止,该功能所要做的就是更新该州的标题。

class NavBar extends Component {
  constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {};
  }

  render() {
    return (
      <div>
        <div id={"myNavbar"}>
          <NavLink
            onClick={() => {
              this.props.clicked("Home Page");
            }}
            to={"/"}
          >
            {" "}
            Home
          </NavLink>
          <NavLink
            onClick={() => {
              this.props.clicked("Payment Page");
            }}
            to={"/payment-status/1"}
          >
            Payment Status
          </NavLink>
        </div>
      </div>
    );
  }
}

Navbar中,当我点击从App作为道具传递的函数时,它将再次回到App组件并运行{{1} },它将更改应用程序的_makeSomething

在此期间,组件titleHomePage收到了PaymentStatus作为道具,因此,在更改州名称时,这两个子组件也会发生变化,因为它们的渲染功能依赖在title上。

例如this.props.title

HomePage

就像我之前说过的那样,通过将您的状态保留在父组件中并将其所需的内容发送给子组件,您应该能够完成所需的工作。

注意:我确实将class HomePage extends Component { constructor(props) { super(props); this._isMounted = true; this.state = {}; } async componentDidMount() { console.log(this.props.match.params.tId); } render() { return ( <div> <div id={"main"}> <p>This is {this.props.title}</p> </div> </div> ); } }标签从anchor更改为<a>,如果您不希望将标签{@ 1}}与react-router-dom一起使用,完全刷新页面。

完整代码可在此处找到:

Edit bold-hugle-wd2o1

答案 2 :(得分:1)

看看Context。这样,您可以将对象从Provider传递到Consumer,甚至可以使用嵌套提供程序覆盖属性https://reactjs.org/docs/context.html

AppContext.js

 export const AppContext = React.createContext({})

App.js


    someFunction = ()=>{
       //implement it
    }

    render() {
        const appContext = {
            someFunction: this.someFunction
        }
        return (
            <AppContext.Provider value={appContext}>
              <Router>
                  <NavBar/>
                  <Route name={'Home'} exact path={'/'} component={HomePage}/>
                  <Route name={'PaymentStatus'} exact path={'/payment-status/:tId'} component={PaymentStatus}/>
              </Router>
            </AppContext>
        );
    }

Homepage.js

class HomePage extends Component {

constructor(props) {
    super(props);
    this._isMounted = true;
    this.state = {};
};

async componentDidMount() {
 console.log(this.props.match.params.tId)
 this.props.appContext.someFunction(); //calls the function of the App-component
};

render() {
    return (
        <div>
            <div id={"main"}>
                <div>
                    <p>This is home page</p>
            </div>
        </div>
    );
  }
}

export default (props) => (
  <AppContext.Consumer>
    {(appContext)=>(
     <HomePage {...props} appContext={appContext}/>
    )}
  </AppContext.Consumer>
)

您也可以将此机制与功能组件一起使用。我通常将Consumer包装到一个额外的组件中。因此,所有可用于组件的值都是常规属性,而不仅仅是在渲染的组件内部。