我有一个listview组件,它由许多子列表项组件组成。
每个子列表项都有一个showSubMenu
布尔状态,它会在列表项旁边显示一些额外的按钮。
此状态应更新以响应用户事件,例如,单击组件DOM节点。
childcomponent:
_handleClick() {
... mutate state
this.props.onClick() // call the onClick handler provided by the parent to update the state in parent
}
然而,更新状态感觉有点不对,因为它会在不同的地方改变状态。
我认为我可以完成它的另一种方式是直接调用this.props.onClick
,然后将子状态作为道具移动到父项中,然后在那里更改状态,并将其作为道具涓涓细流
这些方法中哪些(如果有的话)是惯用的还是更可取的?
答案 0 :(得分:2)
首先,我认为问题的标题并不能很好地描述你的疑问。关于国家应该去哪里更是一个问题。
React的theory说你应该把你的状态放在你能找到的更高的组件中,作为一组组件的唯一真实来源。
对于您申请中的每个州:
- 根据该状态确定呈现某些内容的每个组件。
- 找到一个共同的所有者组件(单个组件位于所有组件之上 需要层次结构中的状态的组件。
- 要么是共同的 所有者或层次结构中较高的其他组件应该拥有 州。
- 如果你找不到合适的组件来拥有它 state,创建一个新组件,只是为了保持状态并添加它 公共所有者组件上方层次结构中的某个位置。
然而,Facebook said的软件工程师:
我们从大型顶级组件开始,提取所有数据 他们的孩子需要,并通过道具传递下去。这导致 中间组件中的许多残缺和无关的代码。 我们在大多数情况下确定的是组件声明和 获取他们自己需要的数据......
当然,正在讨论从商店获取的数据,但我要说的是,在某些情况下理论并不是最佳选择。
在这种情况下,我会说showSubMenu状态只对列表项有意义,以显示几个按钮,因此它是一个很好的选项,将该状态放在子组件中。我说这是一个很好的选择,因为它是一个简单问题的简单解决方案,你提出的另一个选择意味着有类似this的东西:
var GroceryList = React.createClass({
handleClick: function(i) {
console.log('You clicked: ' + this.props.items[i]);
},
render: function() {
return (
<div>
{this.props.items.map(function(item, i) {
return (
<div onClick={this.handleClick.bind(this, i)} key={i}>{item} </div>
);
}, this)}
</div>
);
}
});
如果将来列表视图必须获得该状态的确认以显示某些内容,那么状态应该在父组件中。
然而,我认为这是一条细线,你可以在你的特定情况下做一个有意义的事情,我在我的应用程序中有一个非常相似的情况,这是一个简单的案例,所以我把状态放在孩子身上。明天也许我必须改变它并把状态放在他的父母身上。
答案 1 :(得分:0)
许多组件都取决于相同的状态及其变异,您将遇到两个问题。
此问题有两种解决方案!
示例:
创建上下文
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// Use a Provider to pass the current theme to the tree below.
// Any component can read it, no matter how deep it is.
// In this example, we're passing "dark" as the current value.
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
class ThemedButton extends React.Component {
// Assign a contextType to read the current theme context.
// React will find the closest theme Provider above and use its value.
// In this example, the current theme is "dark".
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
}
// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// Assign a contextType to read the current theme context.
// React will find the closest theme Provider above and use its value.
// In this example, the current theme is "dark".
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
REDUX和REACT-REDUX
import { connect } from 'react-redux'
const App = props => {
return <div>{props.user}</div>
}
const mapStateToProps = state => {
return state
}
export default connect(mapStateToProps)(App)
有关redux和react-redux的更多信息,请查看以下链接: https://redux.js.org/recipes/writing-tests#connected-components