0

私はコンポーネントを持っていますが、renderメソッドとそのコンポーネントの特定のメソッドをオーバーライドできます。 Reactでは、継承は使用できません。関数型プログラミングで合成を使用する方法があるかもしれませんが、レンダリングとすべてのメソッドを別々のコンポーネントに組み立てるにはどうしたらいいですか? componentDidUpdateのようなReactのデフォルトのコンポーネント関数の場合、高次コンポーネント(HoC)に持ち込む別のコンポーネントとして構成することができますか。どのように小道具と状態は、HoCの構成された各コンポーネントを通過するか、またはアクセスされますか。コンポーネントを拡張し、ある方法でメソッドをオーバーライドする例を見つけることは素晴らしいことです。React Reduxアプリケーションで関数プログラミングを使用して継承をシミュレートします

+2

"*には、あなたが*継承を使用することはできませんリアクト"。 – Bergi

答えて

1

"機能的プログラムを使用して継承をシミュレートする"停止、何ですか?あなたはなぜあなた自身のためにそのような負担を選ぶでしょうか?

機能プログラミングは、他のパラダイムで知っている概念を翻訳することではありません。意味のあるプログラムを書く前に、多くの新しいことを学ぶ必要があります。

ここにはBrian Lonsdorf's React Rally 2016 presentationのものがいくつかあります。虹の端にあるポットがどのように見えているかを示すかもしれませんが、そこにはすべて自分のものがあります。

機能的なスタイルを新しいものにしましょう。ドアに古い習慣を残す。要出典 -

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 => 
 
\t (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) 
 
\t \t \t \t \t \t .concat(TodoComp) 
 
\t \t \t \t \t \t .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>

関連する問題