我刚开始学习与Redux的React,所以请宽容。 我跟着Redux开始了,到目前为止,这么好。但是沿着'基本'和'高级'redux doc部分,我结束了我所有组件都被隔离的位置。这完全没问题。除了我的一个组件旨在显示通知,解雇并删除它们。 另一个是需要4个参数才能工作的模态:一个带有标题文本部分,一个用于正文,另一个用于设置是否显示,另一个用于在单击确认按钮时触发确认操作。 当用户想要删除通知时,我的通知组件需要显示模式。两个组件都使用redux处理状态。
以下是一些内容。
下面是notification reducer,它处理dismissing删除和获取通知。很简单。
// The notifications reducer
let initialState = {
isFetching: false,
didInvalidate: false,
notifications: []
}
const notifications = (state = initialState, action) => {
switch (action.type) {
case 'DISMISS':
return {...state, notifications: state.notifications.map(element => element.id === action.id ? {...element, dismissed: !element.dismissed} : element)}
case 'DISMISS_ALL':
return {...state, notifications: state.notifications.map(element => { return {...element, dismissed: false} }) }
case 'DELETE':
return {...state, notifications: state.notifications.filter(element => element.id !== action.id)}
case 'DELETE_ALL':
return {...state, notifications: []}
case 'INVALIDATE':
return {...state, didInvalidate: true}
case 'REQUEST':
return {...state, isFetching: true, didInvalidate: false}
case 'RECEIVE':
return {...state, isFetching: false, didInvalidate: false, notifications: action.posts, lastUpdate: action.receivedAt}
default:
return state
}
}
export default notifications
然后是通知操作。这里的重点是deleteNotification
和deleteAllNotifications
动作,它们必须绑定模态开口并等待其响应,然后触发删除,并且仅在此之后。
那些人需要(我猜测)像fetchNotifications
动作一样工作,调用另一个动作(模态的一个),而不是像fetchNotifications
一样进行数据提取。
// The notifications actions
//@flow
import axios from 'axios'
/**
* NOTIFICATIONS ACTION CREATORS
*/
export const dismissNotification = (id: number) => {
return { type: 'DISMISS', id }
}
export const dismissAllNotifications = () => {
return { type: 'DISMISS_ALL' }
}
export const deleteNotification = (id: number) => {
return { type: 'DELETE', id }
}
export const deleteAllNotifications = () => {
return { type: 'DELETE_ALL' }
}
/**
* DATABASE NOTIFICATIONS ACTION CREATORS
*/
export const invalidate = (uri: string) => {
return { type: 'INVALIDATE', uri }
}
export const requestNotifications = (uri: string) => {
return { type: 'REQUEST', uri }
}
export const receiveNotifications = (uri: string, json: string) => {
return {
type: 'RECEIVE',
uri,
posts: json,
receivedAt: Date.now()
}
}
export const fetchNotifications = (uri: string) => {
return (dispatch: any) => {
dispatch(requestNotifications(uri))
return axios.get(uri)
.then(
response => response.data,
error => console.log('Error', error) // TODO logger les erreurs
)
.then(json => {
dispatch(receiveNotifications(uri, json))
})
}
}
最后,模态的减速器。减速器的要点是通过headerMessage
和bodyMessage
来处理显示(可见或不可见),文本。
id
在这里告诉模态是否必须在一个signle元素或一大堆元素上发送一个删除。这对我来说很脏。它应该只返回一个确认,例如,作为响应将被通知操作捕获的确认。
let initialState = {
showModal: false,
headerMessage: '',
bodyMessage: '',
id: false
}
const modal = (state = initialState, action) => {
switch (action.type) {
case 'MODAL_DISPLAY':
return {...state,
showModal: action.showModal,
headerMessage: action.headerMessage,
bodyMessage: action.bodyMessage,
id: action.id
}
case 'MODAL_HIDE':
return {...state,
showModal: action.showModal,
headerMessage: action.headerMessage,
bodyMessage: action.bodyMessage,
id: action.id
}
default:
return state
}
}
export default modal
为了清楚起见,模态组件和通知组件位于不同的目录中。我希望模态组件可以在任何上下文中使用。这是关于通知的,但是如果我希望它与除通知之外的任何其他组件一起工作,让我们说用户的配置文件,我不应该专门与任何组件绑定。
在我的例子中,notification组件是调用模态的组件。这就是“驱动”全球行为。但我想我并没有很好地建立这一切。这是我的通知组件索引:
//@flow
import React from 'react'
import { render } from 'react-dom'
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose } from 'redux'
import { fetchNotifications } from './store/actions/NotificationsActions'
import NotifiationsApp from './store/reducers/reducerCombiner'
import App from './components/App'
import ModalContainer from '../modal-component/store/containers/ModalContainer'
const loggerMiddleware: any = createLogger()
const composeEnhancers: any = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store: any = createStore(
NotifiationsApp,
composeEnhancers(
applyMiddleware(
thunkMiddleware,
loggerMiddleware
)
)
)
store.dispatch(fetchNotifications('/app_dev.php/notifications/load?offset=0&limit=10'))
render(
<Provider store={store}>
<div>
<App/>
<ModalContainer />
</div>
</Provider>,
document.getElementById('notifications-component')
)
正如你所看到的,我正在调用事实上的ModalContainer
,即'智能'模态组件抽象。
最后,这是我的坏事;将ModalContainer
绑定到通知组件的onConfirm
,我希望在import { connect } from 'react-redux'
import { deleteAllNotifications, deleteNotification } from '../../../notifications-component/store/actions/NotificationsActions'
import { hideModal } from '../actions/ModalActions'
import ModalInstance from '../../components/Modal'
const getModalProperties = modal => {
return modal
}
const mapStateToProps = state => {
return getModalProperties(state.modal)
}
const mapDispatchToProps = dispatch => {
return {
onCancel: () => {
dispatch(hideModal(false, false, '', ''))
},
onConfirm: id => { // BELOW, THIS IS VERY BAD!!
id ? dispatch(deleteNotification(id)) : dispatch(deleteAllNotifications())
dispatch(hideModal(false, '', '', false))
}
}
}
const ModalDisplay = connect(
mapStateToProps,
mapDispatchToProps
)(ModalInstance)
export default ModalDisplay
被触发时“返回”确认事件:
M2_Home: C:\Program Files\apache-maven-3.5.0 (I already tried it with \bin didn't work ether.)
我在这个问题上挣扎。请帮助!
答案 0 :(得分:0)
我不确定自己是否理解正确,但似乎您正在寻找ownProps
。您希望将函数传递给ModalWindow
组件,该组件将在调用确认函数后调用,对吗?这样你就有了像
<ModalContainer onConfirm={myHandler}/>
在这种情况下,您的mapDispatchToProps
需要考虑传递给容器的道具,例如
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onCancel: () => {
dispatch(hideModal(false, false, '', ''))
},
onConfirm: id => { // BELOW, THIS IS VERY BAD!!
id ? dispatch(deleteNotification(id)) : dispatch(deleteAllNotifications())
dispatch(hideModal(false, '', '', false));
ownProps.onConfirm && ownProps.onConfirm(id);
}
}
}
答案 1 :(得分:0)
你一般都在正确的轨道上。方便的是,我刚刚发布了Practical Redux, Part 10: Managing Modals and Context Menus,它演示了如何使用Redux构建和控制模态,上下文菜单和通知。这包括如何处理&#34;返回值&#34;来自模态,因为他们已经关闭。
要专门回答您的问题:清除一个通知的ID与所有通知的处理并不会显得很糟糕&#34;脏&#34;或者&#34;坏&#34;对我来说 - 这种方法应该没问题。