[PReact] Integrate Redux with Preact
Redux is one of the most popular state-management libraries and although not specific to React, it is widely used with it. This is why the author of Preact has released a package called preact-redux, which is a simple wrapper around the main react-redux package that enables it to be used in a Preact application without any other changes to your codebase. In this lesson we refactor a stateful component to use Redux + Redux-thunk. https://github.com/developit/preact-redux
Install:
yarn add redux redux-thunk preact-redux
Set up:
import {h, render} from 'preact'; import {Provider} from 'preact-redux'; import thunk from 'redux-thunk'; import {createStore, applyMiddleware, compose} from 'redux'; import App from './components/App'; import reducer from './reducer'; const initialState = { loading: true, user: null }; const composeEnhancers = typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize... }) : compose; const store = createStore(reducer, initialState, composeEnhancers(applyMiddleware(thunk))); render( <div> <Provider store={store}> <App /> </Provider> </div>, document.querySelector('main'));
Reducer:
export default function (state, action) { switch (action.type) { case 'FETCH_USER': return { user: null, loading: true }; case 'USER_FETCHED': return { user: action.payload, loading: false }; default: return state; } }
Action creator:
const config = { url: 'https://api.github.com/users' }; export function fetchUser(username) { return function (dispatch) { dispatch({type: 'FETCH_USER'}); fetch(`${config.url}/${username}`) .then(resp => resp.json()) .then(user => { dispatch({type: 'USER_FETCHED', payload: user}) }) .catch(err => console.error(err)); } }
Component:
import {h, Component} from 'preact'; import User from './User'; import {fetchUser} from '../actions'; import {connect} from 'preact-redux'; export class Profile extends Component { componentDidMount() { const username = this.props.match.params.user; this.props.fetchUser(username); } render({loading, userState, user}) { return ( <div class="app"> {(loading && !userState) ? <p>Fetching {user}'s profile</p> : <User name={userState.name} image={userState.avatar_url}></User> } </div> ); } } const mapStateToProps = (state) => { return { userState: state.user, loading: state.loading }; }; const mapDispatchToProps = (dispatch) => { return { fetchUser: (username) => dispatch(fetchUser(username)) }; }; export default connect( mapStateToProps, mapDispatchToProps )(Profile);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具