我正在重新创建一个已经在Angular中创建的简单React应用。 React应用程序包含两个组件:一个(menus.js)用于侧面菜单,第二个(content.js)在单击每个链接时将显示菜单中每个项目的内容(就像各种iframe)。在App.js中,我正在进行REST API调用以填充menus.js组件的状态。请注意,这两个组件都在App.js中,如下所示:
App.js
import React,{Component} from 'react';
import Menus from './components/menus';
import Content from './components/content';
class App extends Component {
state = {
menus: []
}
componentDidMount(){
fetch('api address')
.then(res => res.json())
.then((data)=> {
this.setState({menus: data})
})
.catch(console.log)
}
render(){
return (
<div>
<div><Menus menus={this.state.menus} /></div>
<div><Content /></div>
</div>
);
}
}
export default App;
这是menu.js组件;它需要来自App.js的道具(菜单),并使用其中的项目构建菜单链接:
import React from 'react';
import { BrowserRouter as Router, Link,} from "react-router-dom";
const Menus = ({ menus }) => {
return (
<Router>
<div>
<center><h1>Lessons</h1></center>
{menus.map(menu => (
<li key={menu.lesson}>
<Link to={`/lesson/${menu.lesson}`}>{menu.lessonName}</Link>
</li>
))}
</div>
</Router>
);
};
export default Menus;
这是我需要的-如何将项目从同一道具(从App.js)传递到内容组件?仅供参考-每次单击menu.js菜单中的链接时,我都需要这样做(这就是为什么在列表中使用键的原因。简单的想法是,每次菜单时内容都会在内容组件中更新单击菜单组件中的链接。
**content.js**
import React from 'react'
const Content = () => {
return (
<div>{menu.content}</div>
)
};
export default Content
答案 0 :(得分:0)
在您的menu.js
中,将menu
对象附加到Link
...
{menus.map(menu => (
<li key={menu.lesson}>
<Link to={{
pathname: `/lesson/${menu.lesson}`,
state: menu
}}> {menu.lessonName} </Link>
</li>
))}
...
在您的content.js
中收到这样的menu
:
import React from 'react'
const Content = () => {
console.log(props.location.state.menu.content);
return (
<div>{props.location.state && props.location.state.menu.content }</div>
)
};
export default Content
了解更多here
答案 1 :(得分:0)
根据您对问题的描述以及您对所写内容的了解,在我看来,您似乎正在尝试构建一个应用程序,该应用程序可保留菜单,但是内容会根据菜单单击次数而变化。对于简单的应用程序,这就是我将其结构不同的方式。
<ParentmostComponent>
<MenuComponent someProp={this.state.some_data} />
<Switch>
<Route path={"/path"} render={(props) => <Dashboard {...props} someProp={this.state.some_other_data_from_parents} />
</Switch>
</ParentMostComponent>
这将使菜单无论内容在做什么都始终保持在那里,并且您也不必将菜单属性传递给两个组件。
答案 2 :(得分:0)
您的示例使用了反应路由器,因此此答案也使用了它。
首先,将Router
从Menus
上移到App
,以使路由器道具可用于所有组件。然后将您的Content
包装在Route
中以有条件地进行渲染(即,如果路径匹配"/lesson/:lesson"
):
class App extends Component {
state = {
menus: [
{
lesson: '61355373',
lessonName: 'Passing props from parent to sibling in React',
content: 'I am recreating a simple React app…'
},
{
lesson: '27991366',
lessonName: 'What is the difference between state and props in React?',
content: 'I was watching a Pluralsight course on React…'
}
]
}
render() {
const { menus } = this.state
return (
<Router>
<div>
<div><Menus menus={menus}/></div>
<Route path="/lesson/:lesson" render={({ match }) => (
<div><Content menu={menus.find(menu => menu.lesson === match.params.lesson)}/></div>
)}>
</Route>
</div>
</Router>
)
}
}
在render
prop的帮助下,您可以在呈现子组件之前访问路由器道具(在本例中为match.params.lesson
)。我们使用它们将所选菜单传递到Content
。完成!
注意:在兄弟姐妹之间传递道具的基本技巧(没有反应路由器, Redux 等)是lift the state up。