用户与展示组件交互,该组件应该告诉容器组件进行 API 调用或开始捕获音频/摄像头等。
也许你的容器组件做得比它应该做的多。考虑一下 React 组件只做两件事的情况:
- 根据 props 显示 DOM 元素
- 处理用户输入(调度事件)
如果您没有使用 redux,并且想在单击按钮时进行 API 调用,则可能类似于:
class App extends Component {
state = { data: {} }
makeAPICall() {
fetch(url).then(data => this.setState({ data }))
}
render() {
<Child
data={this.state.data}
makeAPICall={this.makeAPICall}
/>
}
}
let Child = ({ data, makeAPICall }) => (
<button onClick={makeAPICall}>Call API!</button>
)
App 组件负责存储全局状态和处理事件,但我们必须通过组件树传递该状态和 App 的处理程序,很可能通过本身永远不会使用这些道具的组件。
通过添加 Redux,您的应用程序现在可以更好地处理 API 调用或打开相机等副作用。中间件!
让这个(蹩脚的)插图帮助你:
因此,现在您的 App 组件可以像所有其他组件一样只是一个普通的展示组件,只需根据存储道具显示数据并在需要时处理任何用户输入/调度操作。让我们使用thunk 中间件更新上面的例子
// actions.js
export let makeAPICall = () => {
return dispatch => {
fetch(url).then(data => dispatch({
type: 'API_SUCCESS',
payload: data,
})).catch(error => dispatch({ type: 'API_FAIL', payload: error }))
}
}
// Child.js
import { connect } from 'react-redux'
import { makeAPICall } from './actions'
let Child = ({ dispatch }) => (
<button onClick={() => dispatch(makeAPICall())}>Call API!</button>
)
export default connect()(Child)
以这种方式思考 React 应用程序非常强大。关注点分离的布局非常好。组件显示内容并处理事件。中间件负责处理任何副作用(如果需要的话),而 store 只是一个对象,它会导致 React 在其数据发生变化时重新渲染。
更新:“模态问题”
React 应用可能有一些全局性的东西,比如模态和工具提示。不要考虑“打开模态”事件。想想“当前模态内容是什么?”。
模态设置可能看起来像这样:
// modalReducer.js
function reducer (state = null, action) {
if (action.type === 'UPDATE_MODAL') {
return action.payload
}
// return default state
return state
}
// App.js
let App = connect(state => ({ modal: state.modal }))(
props =>
<div>
<OtherStuff />
<Modal component={props.modal} />
</div>
)
// Modal.js
let Modal = props =>
<div
style={{
position: 'fixed',
width: '100vw', height: '100vh',
opacity: props.component ? 1 : 0,
}}
>
{props.component}
</div>
// Child.js
let Child = connect()(props =>
<button onClick={e =>
dispatch({
type: 'UPDATE_MODAL'
payload: <YourAwesomeModal />
})
}>
Open your awesome modal!
</button>
)
这只是一个示例,但效果很好!当state.modal 是null 你的模态有0 不透明度并且不会显示。当您发送 UPDATE_MODAL 并传入一个组件时,模式将显示您发送的任何内容并将不透明度更改为 1,以便您可以看到它。稍后您可以发送{ type: 'UPDATE_MODAL', payload: null } 以关闭模式。
希望这能让你思考一些事情!
绝对是read this answer by Dan。他的方法类似,但存储了模态“元数据”而不是组件本身,这更适合 Redux 的幻想,比如时间旅行等。