【发布时间】:2021-10-28 22:06:19
【问题描述】:
我正在学习 React,并试图准确了解应该将多少状态提升到更高的水平。我的理解是,一般来说,只有在具有共同祖先的多个组件需要时才应该提升一个状态。
就我而言,我正在尝试构建一个对被点击做出反应的日历。日历本身应该对被点击做出物理反应,但侧边栏应该显示所选日期的其他信息。目前,整体结构如下:
App
Calendar
Header
Square
Sidebar
LoginInterface
我想要的行为使我相信应用程序应该拥有handleClick(squareNum) 方法的所有权,因为它可以将其作为道具传递给 Squares,但 handleClick 方法将能够影响在侧边栏。当我试图提升我的状态时,我的问题就出现了,而我基本上没有带走整个 Calendar 实现。
显然,仅提升 handleClick(squareNum) 是有问题的,因为 squareNum 未在该级别定义。当我在日历中渲染我的 Squares 时,我将 handleClick 函数作为道具传递给他们,以及 squareNum(字面意思是在循环期间创建 Square 的编号)。为了将 handleClick 提升到 App 中,我还需要提升 Squares 本身的创建。我认为我可以这样做,然后将<div>{row}</div>作为{props.children}传递给Calendar,但我觉得我当时真的在折磨程序的逻辑,而不是坚持只提升的心态编写其他组件所需的代码。
React 文档在https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers 中提到了与我的问题类似的问题,但我认为这里的网格并不完美。虽然我确实想将参数传递给事件处理程序,但我想在中间级组件中执行此操作,我想在 Calendar 中传递 Square 的 id,但我想在 App 中传递 handleClick 本身。
这似乎不是一个不常见的用例,所以我觉得我一定错过了一些 React 的基本内容。谁能建议我如何将中级参数实现到传递的函数道具中,或者类似的东西?
class Calendar extends React.Component{
constructor(props){
super(props)
this.setState({
squares: Array(42).fill(null),
})
}
handeClick(i){
let squares = this.state.squares.slice()
squares[i] = 'clicked!'
this.setState({squares: squares})
}
renderSquare(squareNum){
return(
<Square
//other props
onClick={props.handleClick(squareNum)}
/>
}
render(){
let squareNum = 0;
let cal = [];
return(
for(let i=0;i<5;i++){
let row = [];
for (let j=0;j<7;j++){
row.push(this.renderSquare(squareNum));
squareNum++;
}
cal.push(<div //key //className>{row}</div>);
}
);
}
}
function Square(props){
//irrelevant for this example
}
class App extends React.Component{
constructor(props){
super(props)
this.setState=({
renderedDate: //combined with the squareNum, this allows calculation of which day was clicked
})
/**HandleClick would ideally be here so that the sidebar can have the selected date passed down to it as a prop**/
render(){
<div>
<Calendar //renderedDate />
<Sidebar //props />
</div>
}
}
【问题讨论】:
标签: javascript reactjs state