2016-03-31 29 views
2

Redux ve ReactJS tutklarının çoğundan geçtim. İşlemleri belirleme işlemini anladım => action creators => dispatch => store => daha fazla veri içeren olaylarla görünüm (tek yönlü akış). Benim problemim devleti değiştiren çok basit olaylarla uğraşmak. Biliyorum ki, bütün devletlerin her zaman Redux'da ele alınması gerekmiyor ve yerel durum olayları (React bileşenleri üzerine kurulu) kabul edilebilir bir uygulamadır. Ancak, teknik olarak Redux tüm devlet olaylarını ele alabilir ve bu benim yapmaya çalıştığım şeydir.ReactJS kullanarak Redux ile basit durum güncelleme etkinliği?

İşte sorun. Düğme oluşturan bir React bileşenim var. Bu Düğmede, bir handleClick işlevini tetikleyen bir onClick etkinliği vardır. Düğme durumunu, yapıcı yöntemiyle, Etkin: yanlış olarak ayarladım. İşleç kovulduğunda, setState set isActive: true. HandleClick yöntemi, true olarak değerlendirildiğinde, gövdenin arka plan rengini veya paragraf metninin rengini değiştiren bir işlevi çalıştırırsa, iki yöntem de çalıştırır. Aynı düğmeye tekrar tıklamak durumu tekrar false olarak ayarlar ve gövde rengini veya metin rengini orijinal değerine geri döndürür. Bu Button bileşeni, ayrı bir bileşen içinde iki kez oluşturulur, Başlık. Çok uzun hikaye, iki tane düğmem var. Biri gövde rengini değiştirir, diğeri ise tıklama etkinliğinden sonra p etiket rengini değiştirir.

import * as types from '../constants/ActionTypes'; 

const initialState = { 
    isActive: false 
}; 

export default function Actions(state = initialState, action) { 
    switch (action.type) { 

     case types.TOGGLE_LIGHTS: 
     return [ 
     ...state, 
     { 
      isActive: true 
     } 
     ] 

     default: 
     return state 
    } 
} 
: İşte redüktör için kod

export function dimLights(elem, color) { 
    let property = document.querySelector(elem); 
    if (property.className !== 'lightsOn') { 
     property.style.backgroundColor = color; 
     property.className = 'lightsOn' 
    } 
    else { 
     property.style.backgroundColor = '#FFFFFF'; 
     property.className = 'lightsOff'; 
    } 
} 

export function invertColor(elem, textColor) { 
    let property = document.querySelectorAll(elem), i; 
    for (i = 0; i < property.length; ++i) { 
     if (property[i].className !== 'inverted') { 
      property[i].style.color = textColor; 
      property[i].className = 'inverted' 
     } else { 
      property[i].style.color = '#3B3B3B'; 
      property[i].className = 'notInverted'; 
     } 
    } 
} 

: Burada

import React, {Component} from 'react'; 
import {dimLights, invertColor} from '../../../actions/headerButtons'; 
import { connect } from 'react-redux'; 
import { Actions } from '../../../reducers/reducer'; 

const headerButtonWrapper = 'headerButton'; 
const headerButtonContext = 'hb--ctrls '; 
const dimmedLight = '#333333'; 
const invertedTextColor = '#FFFFFF'; 

export default class Button extends Component { 
    constructor (props) { 
    super(props) 
    this.state = { 
     isActive: false 
    }; 
    } 

    handleClick (e) { 
    e.preventDefault(); 
    let active = !this.state.isActive; 
    this.setState({ isActive: active }); 

     if(this.props.label === "Dim The Lights"){ 
     dimLights('body', dimmedLight); 
     } 
     if(this.props.label === "Invert Text Color"){ 
     invertColor('p', invertedTextColor) 
     } 
    } 

    render() { 
    let hbClasses = headerButtonContext + this.state.isActive; 
    return (
     <div className={headerButtonWrapper}> 
     <button className={hbClasses} onClick={this.handleClick.bind(this)}>{this.props.label}</button> 
     </div> 
    ); 
    } 
} 

renklerini değiştirerek işlemek ithal fonksiyonlar için kod: Burada

Button bileşeni için kod

İşlemlerin kodu şöyledir:

Eğer yardımcı olur
import EasyActions from 'redux-easy-actions'; 

export default EasyActions({ 
    TOGGLE_LIGHTS(type, isActive){ 
     return {type, isActive} 
    } 
}) 

, burada iki Düğme bileşenleri kılan Başlık bileşenidir: Düzen, Hero üç ana bileşeni Başlığını içerir: Nihayet

import React, {Component} from 'react'; 
import Button from './components/Button'; 

const dimmer = 'titleBar--button__dimmer'; 
const invert = 'titleBar--button__invert'; 

export default class Header extends Component { 
    render() { 
    return (
     <div id="titleBar"> 
     <div className="titleBar--contents"> 
      <div className="titleBar--title">Organizer</div> 
      <Button className={dimmer} label="Dim The Lights" /> 
      <Button className={invert} label="Invert Text Color" /> 
     </div> 
     </div> 
    ); 
    } 
} 

, burada Redux (NOT için mağaza ve bağlantıyı içeren kod ve Bilgi. Düğmeler sadece

import React, { Component } from 'react'; 
import { combineReducers } from 'redux'; 
import { createStore } from 'redux' 
import { Provider } from 'react-redux'; 

import Layout from '../components/Layout'; 
import * as reducers from '../reducers/reducer'; 

const reducer = combineReducers(reducers); 
const store = createStore(reducer); 

// This is dispatch was just a test to try and figure this problem out 
store.dispatch({ 
    type: 'TOGGLE_LIGHTS', 
    isActive: true 
}) 
console.log(store.getState()) 

export default class Organizer extends Component { 
    render() { 
    return (
     <Provider store={store}> 
      <div> 
      <Layout /> 
      </div> 
     </Provider> 
    ); 
    } 
} 

Ne yapmak arıyorum bileşeni Tepki yerel devlet mantığını kaldırıp Redux içine) Başlık bileşeni içinde oluşturulur. İthal ettiğim fonksiyonların dağıtım görevlisi olarak hareket etmesi gerektiğini düşünüyorum. Ayrıca, ilk eylemlerimi hatalı şekilde ayarlıyorum gibi hissediyorum. Bu, çevrimiçi ortamda herhangi bir yerde bir cevap bulmak zor, inanılmaz derecede basit bir olaydır. Bunu düzeltmek için neler yapabileceğimi düşünen var mı?

cevap

3

Neredeyse ordasın. Button'unuzu oluşturan bileşen olduğunu varsaydığım Layout bileşeninin kodunu dışarıda bırakmışsınız gibi görünüyor. Buradaki kritik parça, sizin kabınız olacak ve bu, Redux'un connect ile sarılmış olan bileşenini store'a bağlamaktır. Docs for this.More details here.

Ne yapmış:

// containers/App.js - pseudocode 
import {dimLights, invertColor} from '../../../actions/headerButtons'; 

class App extends Component { 
    render() { 
    // Pass in your button state from the store, as well as 
    // your connected/dispatch-ified actions. 
    return (
     <Button 
     state={this.props.buttonState} 
     onClick={this.props.buttonState ? dimLights : invertColor} 
     /> 
    ); 
    } 
} 

function mapStateToProps(state, ownProps) { 
    return { 
    buttonState: state.buttonState 
    }; 
} 
export default connect(mapStateToProps, { 
    // Your action functions passed in here get "dispatch-ified" 
    // and will dispatch Redux actions instead of returning 
    // { type, payload }-style objects. 
    dimLights, invertColor 
})(App); 

Umut yardımcı olur: Redux yerine yapmak istediği ne

// components/Button.js - pseudocode 
import {dimLights, invertColor} from '../../../actions/headerButtons'; 

handleClick() { 
    dimLights(); 
} 

! Redux'un böyle basit şeyler için pek çok boiler plakası vardır, ancak parçaların çoğu saf fonksiyonlar olarak ifade edilebilir, ünite test esnekliğinden çok kazanırsınız ve devtools debugger'u kullanın.