Javascript 我是否需要Redux在左侧显示ItemList,在右侧显示ItemContent?
我真的需要Redux来管理应用程序状态以实现这一点吗?如果没有-如何管理/实施和/或组件的路由和状态 我应该创建组件并嵌套其他组件吗 组件在哪里? 也许这就是HOC的情况? 什么是最好的 接近 要澄清应用程序结构,请参见以下图片: 当前案例和代码: 我的应用程序状态是从传递的,如果你的应用程序简单且小,你不需要使用redux。您可以使用组件状态来实现这一点。你应该从小处着手,只有当你的应用程序足够大时才使用redux 现在,您可以将主要状态保留在组件中,并根据从列表中单击的项目将所需数据传递给组件。范例Javascript 我是否需要Redux在左侧显示ItemList,在右侧显示ItemContent?,javascript,reactjs,redux,react-router,Javascript,Reactjs,Redux,React Router,我真的需要Redux来管理应用程序状态以实现这一点吗?如果没有-如何管理/实施和/或组件的路由和状态 我应该创建组件并嵌套其他组件吗 组件在哪里? 也许这就是HOC的情况? 什么是最好的 接近 要澄清应用程序结构,请参见以下图片: 当前案例和代码: 我的应用程序状态是从传递的,如果你的应用程序简单且小,你不需要使用redux。您可以使用组件状态来实现这一点。你应该从小处着手,只有当你的应用程序足够大时才使用redux 现在,您可以将主要状态保留在组件中,并根据从列表中单击的项目将所需数据传递给
class ItemList extends Component {
constructor(props) {
super(props);
this.state = {
...
// you can keep your data here like
// headings and data for the item content
}
}
.
.
.
// your methods
.
.
.
render() {
const itemList = //map your list here and
// provide a click event which will
// render the respective <ItemContent />
// may be using an id or some index of the array
// depends how you want your data structure to be.
return(
{itemList}
// based on which item from the list is clicked
// you can pass different heading and state
<ItemContent heading={...} data={...} />
);
}
}
编辑:代码中的更改
class ExpenseList extends Component {
constructor(props) {
super(props);
this.state = {
currentItemId = this.props.expenses[0].uid
}
}
handleItemClick = (e) => {
const uid = e.target.id;
this.setState({ currentItemId: uid });
}
details = () => {
const { expenseList } = this.props.expenses;
const [ expense ] = expenseList.filter(expense => {
return expense.uid === this.state.currentItemId;
});
return (
<div>
<ExpenseDetails expenseProps={expense} />
</div>
)
}
render () {
const { expenseList } = this.props.expenses;
const list = expenseList.map(expense =>
<Segment clearing key={expense.uid} >
<a href="#" id={expense.uid} onClick={this.handleItemClick}>
{expense.createdAt}
</a>
<Button floated='right'>
Preview / Print
</Button>
</Segment>
)
return (
<Grid celled='internally'>
<Grid.Row>
<Grid.Column width={5}>
<div>
<h1>Your Expense List:</h1>
<Button onClick={this.props.loadSamples}>Load Sample Expenses</Button>
<Segment.Group raised>
{list}
</Segment.Group>
</div>
</Grid.Column>
<Grid.Column width={11}>
<Segment>
{details()}
</Segment>
</Grid.Column>
</Grid.Row>
</Grid>
)
}
}
注意:我还没有测试过它。对于一个简单的应用程序,我建议你避免重复使用,尤其是如果你是新手。我会使用react路由器,为每个具有不同url的“屏幕”创建一个组件。将状态存储在该屏幕中,并使所有其他组件在其数据和操作中使用道具 例如:
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
} from 'react-router-dom'
import './App.css';
class ExpenseList extends Component {
render () {
const {expenses, selectExpense} = this.props;
return (
<div>{expenses.map(expense => (
<div key={expense.id}>
<h5>{expense.title}</h5>
<button onClick={selectExpense(expense)}>View Details</button>
</div>
))}</div>
)
}
}
class ExpenseDetail extends Component {
render () {
const {expense} = this.props;
return (
<div>
<h1>{expense.title}</h1>
<p>${expense.amount}</p>
</div>
)
}
}
class ExpenseScreen extends Component {
state = {expenses: [], selectedExpense: null}
loadSamples = () => {
// fetch from backend here
this.setState({expenses: [
{id: 1, title: "Expense 1", amount: 1},
{id: 2, title: "Expense 2", amount: 2},
{id: 3, title: "Expense 3", amount: 3},
{id: 4, title: "Expense 4", amount: 4},
]})
}
selectExpense = (expense) => (clickEvent) => {
this.setState({selectedExpense: expense});
}
render() {
return(
<div className="expense-container">
<Link to="/about">About</Link>
<div className="left-col">
<h1>Your Expense List:</h1>
<button onClick={this.loadSamples}>Load Sample Expenses</button>
<ExpenseList expenses={this.state.expenses} selectExpense={this.selectExpense} />
</div>
<div className="right-col">
{this.state.selectedExpense && <ExpenseDetail expense={this.state.selectedExpense} />}
</div>
</div>);
}
}
const About = () => (
<div>
<h2>About</h2>
<Link to="/">Home</Link>
</div>
)
class App extends Component {
render() {
return (
<div className="App">
<Router>
<Switch>
<Route path="/" exact component={ExpenseScreen} />
<Route path="/about" component={About} />
</Switch>
</Router>
</div>
);
}
}
export default App;
谢谢你的回答。你能给我看看你的代码吗?如果两个组件对应于不同的URL,您如何在一个屏幕上呈现它们?正如我在帖子中所问的,您是否建议我应该创建组件并在其中嵌套其他组件?您是否也可以更正我发布的代码?我尝试用你的解决方案来解决编译问题,但没有成功。我只想看看和理解我的代码和react-router的案例。谢谢你的解决方案!我一直在看react路由器的例子,但仍然不知道如何调整它以适应我的情况。我必须把所有的道具都传给我的组件。不仅仅是身份证。非常感谢,你能帮我完成那个onClick活动吗?如何使用onClick传递道具?用最新的更新了我的帖子code@karolis2017更新了我的anwser。检查它是否适合你。
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
} from 'react-router-dom'
import './App.css';
class ExpenseList extends Component {
render () {
const {expenses, selectExpense} = this.props;
return (
<div>{expenses.map(expense => (
<div key={expense.id}>
<h5>{expense.title}</h5>
<button onClick={selectExpense(expense)}>View Details</button>
</div>
))}</div>
)
}
}
class ExpenseDetail extends Component {
render () {
const {expense} = this.props;
return (
<div>
<h1>{expense.title}</h1>
<p>${expense.amount}</p>
</div>
)
}
}
class ExpenseScreen extends Component {
state = {expenses: [], selectedExpense: null}
loadSamples = () => {
// fetch from backend here
this.setState({expenses: [
{id: 1, title: "Expense 1", amount: 1},
{id: 2, title: "Expense 2", amount: 2},
{id: 3, title: "Expense 3", amount: 3},
{id: 4, title: "Expense 4", amount: 4},
]})
}
selectExpense = (expense) => (clickEvent) => {
this.setState({selectedExpense: expense});
}
render() {
return(
<div className="expense-container">
<Link to="/about">About</Link>
<div className="left-col">
<h1>Your Expense List:</h1>
<button onClick={this.loadSamples}>Load Sample Expenses</button>
<ExpenseList expenses={this.state.expenses} selectExpense={this.selectExpense} />
</div>
<div className="right-col">
{this.state.selectedExpense && <ExpenseDetail expense={this.state.selectedExpense} />}
</div>
</div>);
}
}
const About = () => (
<div>
<h2>About</h2>
<Link to="/">Home</Link>
</div>
)
class App extends Component {
render() {
return (
<div className="App">
<Router>
<Switch>
<Route path="/" exact component={ExpenseScreen} />
<Route path="/about" component={About} />
</Switch>
</Router>
</div>
);
}
}
export default App;