朋友下午好, 我的页面和组件安排在应用程序的主类中,我可以将某些结果从任何组件或页面传递到主类,并将此属性从主类传递到任何其他组件。 为了很好地描述问题,我将举一个例子:
这是我的主类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传递给任何组件。 谢谢。
答案 0 :(得分:1)
您可以在App类中对方法进行decalare,然后通过prop将其传递给另一个组件。 例如 然后,您可以在MyComponent中调用此方法,并将一些值传递给它。这是将值从子组件传递到父组件的方法。在App中的方法中,您可以简单地使用setState。 剩下要做的就是通过prop将这个新的state属性传递给另一个组件。 要在组件使用过程中传递价值,必须改变
<Route component={SomeComponent}
收件人
<Route render={() => <SomeComponent somethingChanged={this.somethingChangedMethodInAppClass}}/>
希望有帮助!
编辑:您还可以使用Redux将状态外部化并在子组件中重用
答案 1 :(得分:1)
您在这里有两个选择:
将所有状态保留在父组件中,,然后将应用程序传递给子组件,甚至可以更新父状态的动作。如果另一个孩子使用该状态,则该孩子也将被重新呈现。
我根据您的情况创建了一个小示例。
在此示例中,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>
);
}
}
组件HomePage
和PaymentStatus
将以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
。
在此期间,组件title
和HomePage
收到了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一起使用,完全刷新页面。
完整代码可在此处找到:
答案 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包装到一个额外的组件中。因此,所有可用于组件的值都是常规属性,而不仅仅是在渲染的组件内部。