在React Redux应用程序中使用函数式编程来模拟继承 [英] Simulate inheritance using functional programming in React Redux application

查看:185
本文介绍了在React Redux应用程序中使用函数式编程来模拟继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个组件,我希望能够覆盖该组件中的 render 方法和某些方法。在React中,你不能使用继承。在函数式编程中可能有一种使用合成的方法,但是如何真正将渲染和所有方法合成为单独的组件。对于React默认的组件函数(如 componentDidUpdate ),您是否可以将其组合为一个独立的组件,并将其引入到高阶组件(HoC)中。道具和状态如何通过或访问HoC的每个组成部分。找到一个扩展组件并以某种方式覆盖某个方法的例子会很棒。

使用功能程序继承 - 停止,什么?为什么你会为自己选择这样的负担?



函数式编程并不是要翻译其他范式中的概念。在开始编写有意义的程序之前,您需要学习许多新东西。



以下是 Brian Lonsdorf 2016年的反应拉力赛报告 - 它可能会告诉你彩虹尽头的底池是什么样的,但到达那里的东西是全部的它自己的。

让功能风格变得新颖而不同;



const {withReducer} = Recomposeconst Reducer = (状态,动作)=> g(状态,f(动作))),映射:f =>减速器((状态,动作) (状态,动作))),concat:o => Reducer((state,action)=> o.fold(g(state,action),action))})const appReducer = Reducer (state,action)=> {switch(action.type){case'set_visibility_filter':return Object.assign({},state,{visibilityFilter:action.filter})default:return state}})const todoReducer = Reducer((state,action)=> {switch(action.type){case'new_todo':const t = {id:0,title:action.payload.title} return Object.assign({},state,{ todos:state.todos.concat(t)})默认:return state}})const Component = g =>({fold:g,contramap:f =>分量(x => g(f(x))),concat:other => Component(x =>< div> {g(x)} {other.fold(x)}< / div>)})const classToFn = C => (道具)=> < C {...道具} /> const Hoc = g =>({fold:g,concat:other => Hoc(x => g(other.fold(x)))})// Example // ======== ============== const todoApp = appReducer.concat(todoReducer).contramap(action => Object.assign({filter:'all'},action)).map(s = > Object.assign({},s,{lastUpdated:Date()}))const hoc = Hoc(withReducer('state','dispatch',todoApp.fold,{todos:[]}))const Todos = (状态,调度)=>< div>< span>过滤器:{state.visibilityFilter}< / span>< ul> {state.todos.map((t,i) =>< li key = {i}> {t.title}< / li>)}< / ul>< button onClick = {()=> dispatch({type:'new_todo',有效载荷:{title:'New todo'}})}>添加待办事项< / button><按钮onClick = {()=> dispatch({type:'set_visibility_filter'})}> Set Visibility< / button>< / div>)const TodoComp = Component(classToFn(Todos))const Header = Component(s =&g t;< h1>现在查看{s}< / h1>)const ProfileLink = Component(u => < a href = {`/ users / $ {u.id}`}> {u.name}< / a>)const App = Header.contramap(s => s.pageName).concat(TodoComp ).concat(ProfileLink.contramap(s => s.current_user)).fold({pageName:'Home',current_user:{id:2,name:'Boris'}})ReactDOM.render(App,document。 getElementById('container'))

< script src = https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js\"></script><script src =https://cdnjs.cloudflare.com/ ajax / libs / react / 15.1.0 / react-dom.min.js>< / script>< script src =https://cdnjs.cloudflare.com/ajax/libs/recompose/0.26.0 /Recompose.min.js\"></script><div id =container> <! - 此元素的内容将被您的组件替换。 - >< / div>

I have a component, I want to be able to override the render method and certain methods in that component. In React you cannot use inheritance. There could be a way using composition in functional programming, but how would you actually go about composing the render and all the methods into separate components. For React default component functions such as componentDidUpdate, would you be able to composition it as a separate component that you bring in to a higher-order component (HoC). How would props and state be passed through or accessed in each composed component of a HoC. It would be great to find an example of extending a component and overriding a method in some way.

解决方案

"Simulate inheritance using functional progr-" Stop, what? Why would you elect such a burden for yourself?

Functional programming isn't about translating the concepts you know in other paradigms. You'll need to learn many new things before you can begin to write meaningful programs.

Here's some stuff from Brian Lonsdorf's React Rally 2016 presentation – it might show you what the pot at the end of the rainbow can look like, but getting there is thing all on its own.

Let functional style be new and different; leave old habits at the door.

const { withReducer } = Recompose

const Reducer = g =>
({
  fold: g,
  contramap: f =>
    Reducer((state, action) => g(state, f(action))),
  map: f =>
    Reducer((state, action) => f(g(state, action))),
  concat: o =>
    Reducer((state, action) => o.fold(g(state, action), action))
})

const appReducer = Reducer((state, action) => {
  switch (action.type) {
    case 'set_visibility_filter':
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    default:
      return state
  }
})

const todoReducer = Reducer((state, action) => {
  switch (action.type) {
    case 'new_todo':
      const t = { id: 0, title: action.payload.title }
      return Object.assign({}, state, {
        todos: state.todos.concat(t)
      })
    default:
      return state
  }
})

const Component = g =>
({
  fold: g,
  contramap: f =>
    Component(x => g(f(x))),
  concat: other =>
    Component(x => <div>{g(x)} {other.fold(x)}</div>)
})


const classToFn = C =>
	(props) => <C {...props} />
  
const Hoc = g =>
({
  fold: g,
  concat: other =>
    Hoc(x => g(other.fold(x)))
})

// Example
// ======================

const todoApp = appReducer.concat(todoReducer)
                .contramap(action => Object.assign({filter: 'all'}, action))
                .map(s => Object.assign({}, s, {lastUpdated: Date()}))

const hoc = Hoc(withReducer('state', 'dispatch', todoApp.fold, {todos: []}))

const Todos = hoc.fold(({ state, dispatch }) =>
  <div>
    <span>Filter: {state.visibilityFilter}</span>
    <ul>
      { state.todos.map((t, i) => <li key={i}>{t.title}</li>) }
    </ul>
    <button onClick={() =>
      dispatch({ type: 'new_todo', payload: {title: 'New todo'}})}>
      Add Todo
    </button>
    <button onClick={() =>
      dispatch({ type: 'set_visibility_filter' })}>
      Set Visibility
    </button>
  </div>
)

const TodoComp = Component(classToFn(Todos))

const Header = Component(s => <h1>Now Viewing {s}</h1>)

const ProfileLink = Component(u => <a href={`/users/${u.id}`}>{u.name}</a>)


const App = Header.contramap(s => s.pageName)
						.concat(TodoComp)
						.concat(ProfileLink.contramap(s => s.current_user))
            .fold({ pageName: 'Home',
                    current_user: {id: 2, name: 'Boris' } })

ReactDOM.render(
  App,
  document.getElementById('container')
)

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/recompose/0.26.0/Recompose.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

这篇关于在React Redux应用程序中使用函数式编程来模拟继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆