在 React/Redux 的点击函数中传递道具
Passing a Prop in an On Click Function in React/Redux
我有一个 onClick
函数,它调用一个名为 toggleButton
的动作创建器来更改 this.props.UserOpen
的状态。以下代码有效并将属性 UserOpen
设置为 true。
class ButtonComponent extends Component {
render() {
return (
<div >
<a href="javascript:;" onClick={this.props.toggleButton.bind(this, true)}>Click Me!</a>
</div>
);
}
}
function mapStateToProps(state) {
return { UserOpen: state.UserOpen };
}
function mapDispatchToProps(dispatch){
return bindActionCreators({toggleButton}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(ButtonComponent);
这是我要合并的违规代码。
<a href="javascript:;" onClick={this.props.toggleButton.bind(this, {!this.props.UserOpen})}>Click Me!</a>
调用 onClick
时,我想在 true
和 false
之间切换 toggleButton
参数中的 UserOpen 属性。这是可能的还是我必须创建一个单独的函数来调用动作创建者?
编辑——更多代码
actions.js
export function toggleButton(status){
return {
type: BUTTON_OPEN,
payload: status
};
}
reducer.js
const INITIAL_STATE = { buttonOpen:true};
export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case BUTTON_OPEN:
return {...state, buttonOpen: action.payload};
}
return state;
}
如果只是切换状态的布尔值 属性,那么您可以在 reducer 中轻松完成:
case SOME_TYPE: {
return Object.assign({}, state, {
UserOpen: !state.UserOpen
})
}
在这种情况下,您的动作创建者应该只有 type
属性:
function toggleButton() {
return {
type: SOME_TYPE
}
}
如果你坚持要从组件中传递一个属性,你可以这样做:
class ButtonComponent extends Component {
render() {
this.toggleButton = this.props.toggleButton.bind(this)
return (
<div>
<a href="javascript:;" onClick={function() { this.toggleButton(!this.props.UserOpen) }}> Click Me!</a>
</div>
);
}
}
您不能更改组件的道具,除非它是数组或对象。如果你真的想改变道具,那么你可以将它包装到一个对象中并使用值来代替。
UserOpen 将是一个包含 value
的对象。
<a href="javascript:;" onClick={this.props.toggleButton.bind(this, {!this.props.UserOpen.value})}>Click Me!</a>
但是,更新状态而不是道具是最佳实践。
<a href="javascript:;" onClick={this.toggleButton(this)}>Click Me!</a>
尽可能不要在 render 方法中绑定值是个好主意,这也是为了可读性,比如:
toggleButton = () => {
this.props.toggleButton(!this.props.userOpen)
}
render() {
return (
<div >
<a href="javascript:;" onClick={this.toggleButton}>Click Me!</a>
</div>
);
}
我有一个 onClick
函数,它调用一个名为 toggleButton
的动作创建器来更改 this.props.UserOpen
的状态。以下代码有效并将属性 UserOpen
设置为 true。
class ButtonComponent extends Component {
render() {
return (
<div >
<a href="javascript:;" onClick={this.props.toggleButton.bind(this, true)}>Click Me!</a>
</div>
);
}
}
function mapStateToProps(state) {
return { UserOpen: state.UserOpen };
}
function mapDispatchToProps(dispatch){
return bindActionCreators({toggleButton}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(ButtonComponent);
这是我要合并的违规代码。
<a href="javascript:;" onClick={this.props.toggleButton.bind(this, {!this.props.UserOpen})}>Click Me!</a>
调用 onClick
时,我想在 true
和 false
之间切换 toggleButton
参数中的 UserOpen 属性。这是可能的还是我必须创建一个单独的函数来调用动作创建者?
编辑——更多代码
actions.js
export function toggleButton(status){
return {
type: BUTTON_OPEN,
payload: status
};
}
reducer.js
const INITIAL_STATE = { buttonOpen:true};
export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case BUTTON_OPEN:
return {...state, buttonOpen: action.payload};
}
return state;
}
如果只是切换状态的布尔值 属性,那么您可以在 reducer 中轻松完成:
case SOME_TYPE: {
return Object.assign({}, state, {
UserOpen: !state.UserOpen
})
}
在这种情况下,您的动作创建者应该只有 type
属性:
function toggleButton() {
return {
type: SOME_TYPE
}
}
如果你坚持要从组件中传递一个属性,你可以这样做:
class ButtonComponent extends Component {
render() {
this.toggleButton = this.props.toggleButton.bind(this)
return (
<div>
<a href="javascript:;" onClick={function() { this.toggleButton(!this.props.UserOpen) }}> Click Me!</a>
</div>
);
}
}
您不能更改组件的道具,除非它是数组或对象。如果你真的想改变道具,那么你可以将它包装到一个对象中并使用值来代替。
UserOpen 将是一个包含 value
的对象。
<a href="javascript:;" onClick={this.props.toggleButton.bind(this, {!this.props.UserOpen.value})}>Click Me!</a>
但是,更新状态而不是道具是最佳实践。
<a href="javascript:;" onClick={this.toggleButton(this)}>Click Me!</a>
尽可能不要在 render 方法中绑定值是个好主意,这也是为了可读性,比如:
toggleButton = () => {
this.props.toggleButton(!this.props.userOpen)
}
render() {
return (
<div >
<a href="javascript:;" onClick={this.toggleButton}>Click Me!</a>
</div>
);
}