2017-08-15 1 views
1

を反応させる:SETSTATE /外部関数の状態を使用して、この擬似コードを考慮

component.js

... 
import {someFunc} from "./common_functions.js" 

export default class MyComp extends Component { 
    constructor(props) { 
     super(props); 

    this.someFunc = someFunc.bind(this); 

    this.state = {...}; 
    } 

    _anotherFunc =() = > { 
     .... 
     this.someFunc(); 
    } 

    render() { 
     ... 
    } 
} 

common_functions.js

export function someFunc() { 
    if(this.state.whatever) {...} 
    this.setState{...} 
} 

私はComponentのコンテキストに機能someFunc()を結合する方法は?私はさまざまなコンポーネントでそれを使用するので、1つのファイルでそれらを収集するのが理にかなっています。今、「未定義のものは読めません」というエラーが表示されます。 thisのコンテキストは不明です...

+0

はあなた 'someFunc'に' export'を削除し、あなた 'MYCOMPの内側に、この機能を入れてみました'クラス? – Jacky

+0

もちろんジャッキーはうまくいくでしょう。しかし、いくつかのコンポーネントで 'someFunc()'を使用しています... – Stophface

+1

あなたの状態を管理するためにHOCを使用し、ラップされたコンポーネントに小道具を渡すことができます。 https://facebook.github.io/react/docs/higher-order-components.html#use-hocs-for-cross-cutting-concerns –

答えて

2

コンポーネントのローカルステートであるため、コンポーネントの外側にステートを設定することはできません。共有されている状態を更新する必要がある場合は、ストア(reduxストア)を作成します。

あなたのケースでは、ある場所でsomeFunctionを定義し、特定の状態変数または状態全体を渡すことができます。 someFunctionで完了したら、変更された状態を返し、setStateを使用してコンポーネント内に戻します。

export function someFunc(state) { 
    if(state.whatever) {...} 
    const newState = { ...state, newValue: whateverValue } 
    return newState 
} 

_anotherFunc =() = > { 
     .... 
     const newState = this.someFunc(this.state); 
     this.setState({newValue: newState}); 
    } 
+0

理由は、私は還元機能を使用したくない理由は、コンポーネントのローカル状態からの更新はスタイリングのためだけだからです。私には、コンポーネントのスタイリングのためだけreduxを使用していない合理的な音... – Stophface

0

これはすべてあなたが達成しようとしているものによって決まります。一見すると2つの選択肢があります。 1つは子コンポーネントを作成し、2つは作成します:reduxはすべての子コンポーネント間に特異状態を提供するため、reduxを使用します。

最初のオプション:

export default class parentClass extends Component { 
    state = { 
     param1: "hello". 
    }; 

    render() { 
     return (
      <Child param1={this.state.param1}/> 
     ); 
    } 
} 
class Child extends Component { 
    render() { 
     console.log(this.props.param1); 
     return (
      <h1>{this.props.param1}</h1> 
     ); 
    } 
} 

今すぐ上記の子コンポーネントはprops.param1は、それが機能をレンダリング親から渡された小道具から定義されています。

上記は機能しますが、私はあなたが '共通の'機能セットを確立しようとしているのを見ることができます。オプション2の並べ替えは、あなたのアプリケーション/プロジェクトの特異状態を作成することによって、その方法を提供します。 あなたがそれを掛けてしまえば使い始めたのはかなり簡単です。 http://redux.js.org/docs/basics/UsageWithReact.htmlの設定を省略します。

そうのような減速を行います。

import * as config from './config';//I like to make a config file so it's easier to dispatch my actions etc 
//const config.state = {param1: null} 
//const config.SOME_FUNC = "test/SOME_FUNC"; 

export default function reducer(state = config.state, action = {}) { 
    switch(action.type) { 
     case config.SOME_FUNC: 
      return Object.assign({}, state, { 
       param1: action.param1, 
      }); 
     break; 
     default: 
      return state; 
     } 
    } 
} 

は、お店のためにあなたの減速にそれを追加します。

すべてのコンポーネントをプロバイダにラップします。

ReactDOM.render(
    <Provider store={store} key="provider"> 
     <App> 
    </Provider>, 
    element 
); 

これで、プロバイダのすべての子コンポーネントでredux connectを使用できるようになりました。そのよう

import React, {Component} from 'react'; 
import {connect} from 'react-redux'; 

@connect(
    state => (state), 
    dispatch => ({ 
     someFunc: (param1) => dispatch({type: config.SOME_FUNC, param1: param1}), 
    }) 
) 
export default class Child extends Component { 

    eventFunction = (event) => { 
     //if you wanted to update the store with a value from an input 
     this.props.someFunc(event.target.value); 
    } 

    render() { 
     return (
      <h1>{this.props.test.param1}</h1> 
     ); 
    } 
} 

あなたはReduxのhttps://github.com/redux-saga/redux-sagaこれをチェックアウトするために使用されます。これがあなたの最終目標です!サガは素晴らしいです!あなたがつかまえられたら、私に知らせてください!

+0

理由は、私は還元を使用したいのですが、コンポーネントのローカル状態からの更新はスタイリングのためだけです。私には、部品のスタイリングだけのためのreduxを使用することは合理的に聞こえません... – Stophface

+0

それは十分です。それでは、あなたは子供に小道具を渡すか、someFunc 'function someFunc(params)' – sourRaspberri

0

これを管理する一種の外部ライブラリを使うことをお勧めします。他の人たちが示唆しているように、ReduxとMobXはこれに適しています。他のすべてのコンポーネントをラップするために上位コンポーネントを使用することもオプションです。

しかし、ここでは、上記のものに代わるソリューションです:あなたは標準のJavaScriptクラスを使用します(コンポーネントに反応しない)、あなたはそのクラスから呼び出している関数にthisに渡すことができ


が。

これはかなり簡単です。以下では、状態が別のクラスの関数から変更された単純な例を作成しました。あなたを

export default class Parent extends Component { 
 

 
    constructor() { 
 
     super(); 
 
     this.state = { 
 
     applyGlobalCss: false, 
 
     }; 
 
    } 
 
    
 
    toggleCss() { 
 
     this.setState({ applyGlobalCss: !this.state.applyGlobalCss }); 
 
    } 
 

 
    render() { 
 
     return (
 
      <Child css={this.state.applyGlobalCss} onToggle={this.toggleCss} /> 
 
     ); 
 
    } 
 
}

、その後、子コンポーネントで:見てみましょう:あなたはあなたのコールバックを定義し、グローバル状態を管理

class MyApp extends React.Component { 
 

 
    constructor() { 
 
    super(); 
 
    this.state = {number: 1}; 
 
    } 
 

 
    double =() => { 
 
    Global.myFunc(this); 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     <p>{this.state.number}</p> 
 
     <button onClick={this.double}>Double up!</button> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class Global { 
 
    static myFunc = (t) => { 
 
    t.setState({number: t.state.number*2}); 
 
    } 
 
} 
 

 
ReactDOM.render(<MyApp />, document.getElementById("app"));
<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> 
 
<div id="app"><div>

+0

を使ってください。なぜなら、reduxを使いたくないのは、コンポーネント内のローカル状態からの更新がスタイリングのためだけだからです。私には、部品のスタイリングだけのためのreduxを使用することは合理的に聞こえません... – Stophface

+0

@Stophface、大丈夫です。あなたが気づいたかどうかは分かりませんが、これは還元的な解決策ではありません。 :) – Chris

+0

私は気づいた。あなたも私に還元してくれたことを指摘してください。それはなぜ私が追加したものなのですか? – Stophface

0

親コンポーネントの例小道具やコールバックは次のように使用できます:

export default class Child extends Component { 
 

 
    render() { 
 
     console.log(this.props.css); 
 
     return (
 
      <div onClick={this.props.onToggle}> 
 
      </div> 
 
     ); 
 
    } 
 
} 
 

 
Child.propTypes = { 
 
    onToggle: PropTypes.func, 
 
    css: PropTypes.bool, 
 
};

0

も成分の外で使用することができるSETSTATEの関数形式があります。

SETSTATEの署名があるので、これは可能です:

* @param {object|function} partialState Next partial state or function to 
*  produce next partial state to be merged with current state. 
* @param {?function} callback Called after state is updated. 

参照ダンのつぶやき:https://twitter.com/dan_abramov/status/824308413559668744

関連する問題