我正在React中学习Redux。我在React中使用Redux进行模态开发。我的代码如下所示
render() {
return (
<Modal id="addressModal" open={this.props.controlModal} onClose={this.props.action}>
<Provider store={store}>
{this.props.addresObj ? (
<Modal.Header>Address Details</Modal.Header>
) : (
<Modal.Header>Insert Address</Modal.Header>
)}
<Modal.Content>
<ModalElement
update={this.update}
element={this.props.addresObj}
errors = {this.state.errors}
update_state_photo={this.update_state_photo}
address={this.props.address}
action={this.props.action}
/>
</Modal.Content>
<Modal.Actions>
{this.props.addresObj ? (
<Button
positive
icon="checkmark"
labelPosition="right"
onClick={this.closeModal}
content="OK"
/>
) : (
<Button
positive
icon="checkmark"
labelPosition="right"
onClick={this.insertAddress}
content="Save"
/>
)}
</Modal.Actions>
</Provider>
</Modal>
);
}
}
(我是否正确使用<Provider store={store}>
?)在子组件中,我无法使用Redux语法。就像我使用这个export default connect()(EditableRow);
一样,我得到了错误(组件执行未在该组件上完成,需要执行)。如果我使用这种语法export default EditableRow;
,则不会出现任何错误。
可能是我无法正确表达我的问题。
这是我的仓库https://github.com/afoysal/mern/blob/master/client/src/components/ModalBody.js
我遇到了错误。
如何在React Modal中使用Redux?
答案 0 :(得分:3)
这里的问题来自使用React portals
门户提供了一种一流的方式来将子级呈现到父组件的DOM层次结构之外的DOM节点中。
Portal允许在另一个DOM下不渲染React元素。经过简化,这看起来像
const ComponentA = ReactDOM.createPortal(
<CoolComponent />,
document.getElementById('banner'),
)
const ComponentB = ReactDOM.createPortal(
<SuperCoolComponent />,
document.getElementById('footer'),
)
因此,在ComponentA
中,Provider
不会看到ComponentB
。
您可能会看这个page,但是它并不能完全描述您遇到的问题。
如果查看<Modal>
组件源,它将使用React.createPortal
进行渲染并失去父级的提供者。
我看到一个解决方法
store
中提取<Provider/>
在使用<Provider>
之后立即创建新的<Modal>
。
// ModelBody.js
import { Provider, ReactReduxContext } from 'react-redux';
//...
render() {
return (
<ReactReduxContext.Consumer>
{((ctx) => (
<Modal id="addressModal" open={this.props.controlModal} onClose={this.props.action}>
<Provider store={ctx.store}> /* make store available in Portal */
{this.props.addresObj ? (
<Modal.Header>Address Details</Modal.Header>
) : (
<Modal.Header>Insert Address</Modal.Header>
)}
/* other code from Model.js */
</Provider>
</Modal>
)).bind(this) // Dont forget to bind this
}
</ReactReduxContext.Consumer>
答案 1 :(得分:1)
我希望你没有把所有东西都正确包装,
打包后,可在整个应用中访问,
如redux所述,必须有单一的真理来源,
一定要遵循原则。
// ModelBody.js
import { Provider, ReactReduxContext } from 'react-redux';
//...
render() {
return (
<ReactReduxContext.Consumer>
{((ctx) => (
<Provider store={ctx.store}>
<Modal id="addressModal" open={this.props.controlModal} onClose={this.props.action}>
/* make store available in Portal */
{this.props.addresObj ? (
<Modal.Header>Address Details</Modal.Header>
) : (
<Modal.Header>Insert Address</Modal.Header>
)}
/* other code from Model.js */
</Modal>
</Provider>
)).bind(this) // Dont forget to bind this
}
</ReactReduxContext.Consumer>
或尝试包装整个应用index.jsx
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rootReducer from './reducers'
import App from './components/App'
const store = createStore(rootReducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)