2017-04-13 12 views
6

Pracuję nad aplikacją React i dotarłem do punktu, w którym będę potrzebował Redux, aby poradzić sobie z niektórymi aspektami.Dodawanie Redux do istniejącej aplikacji React

Po przeczytaniu kilku tutoriali utknąłem na tym, jak sprawić, by moje "inteligentne" komponenty "dusiły" i przenosiły funkcje do moich działań i reduktorów.

Na przykład jeden aspekt aplikacji jest bardziej stylem listy rzeczy do zrobienia.

Jeden z moich klas zaczyna tak:

export default class ItemList extends React.Component { 
    constructor() { 
    super(); 
    this.state = { items: [], 
        completed: [], 
        }; 
    this.addItem = this.addItem.bind(this); 
    this.completeItem = this.completeItem.bind(this); 
    this.deleteItem = this.deleteItem.bind(this); 
    } 

    addItem(e) { 
    var i = this.state.items; 
    i.push({ 
     text: this._inputElement.value, 
     paused: false, 
     key: Date.now() 
    }); 
    this.setState({ items: i }); 
    e.preventDefault(); 
    this._inputElement.value = ''; 
    this._inputElement.focus(); 
    } 

    completeItem(e) { 
    this.deleteItem(e); 
    var c = this.state.completed; 
    c.push({ 
     text: e.target.parentNode.parentNode.getElementsByClassName('item-name')[0].innerHTML, 
     paused: false, 
     key: Date.now() 
    }); 
    this.setState({ completed: c }); 
    } 

    deleteItem(e) { 
    var i = this.state.items; 
    var result = i.filter(function(obj) { 
     return obj.text !== e.target.parentNode.parentNode.getElementsByClassName('item-name')[0].innerHTML; 
    }); 
    this.setState({ items: result }); 
    } 

    // ... more irrelevant code here ... 

    // there's a function called createTasks that renders individual items 

    render() { 
    var listItems = this.state.items.map(this.createTasks); 

    return <div className="item-list"> 
     <form className="form" onSubmit={this.addItem}> 
     <input ref={(a) => this._inputElement = a} 
       placeholder="Add new item" 
       autoFocus /> 
     <button type="submit"></button> 
     </form> 

     {listItems} 
    </div>; 
    } 
} 

Więc, jak widać, jest to bardzo logiczny ciężki. Zacząłem dodanie Redux dodając <Provider> w moim pliku indeksu, wykonane podstawowego pliku reduktory, który jest dość pusta do tej pory:

import { combineReducers } from 'redux'; 

const itemList = (state = {}, action) => { 

}; 

// ... other irrelevant reducers 

const rootReducer = combineReducers({ 
    itemList, 
    // ... 
}); 

export default rootReducer; 

... i zrobiłem plik działań, które nie jeszcze wiele w nim masz.

Byłem stara się dowiedzieć:

  • Większość działań Widziałem przykłady po prostu wrócić jakiś JSON, co mogę zwrócić w reduktor, który wykorzystuje to, że moje JSON komponent może używać ?
  • Ile elementów mojej logiki komponentowej można użyć do ponownego użycia, czy powinienem ją po prostu zapomnieć? Jaki jest najlepszy sposób na to, aby ponownie użyć tyle kodu, ile napisałem, jak to możliwe?

Odpowiedz

16

Przede wszystkim należy zrozumieć ogólny obraz działania reduxu z reakcją.

Zanim do tego dojdziemy, musimy najpierw zrozumieć, czym są inteligentne komponenty i głupie komponenty.

Komponenty Inteligentne

  1. Wszystko logika kod musi być obsługiwane tutaj
  2. Nazywane są również pojemniki.
  3. Łączą się ze sklepem (inaczej zarządzanie stanem), aby zaktualizować składniki.

Dumb Komponenty

  1. Oni po prostu czytają rekwizyty z kontenerów i czynią Cię komponenty
  2. To dopiero widok interfejsu użytkownika i nie powinny zawierać żadnych logicznych.
  3. Wszystkie stylizacje/html/css występują w Twoich głupich komponentach.

Here to niesamowity artykuł, do którego można przejść, aby zrozumieć inteligentne i głupie elementy, jeśli nadal masz wątpliwości.

Ok, teraz spróbujmy zrozumieć, jak Redux prace: -

  • inteligentnego składników (aka pojemniki) współdziałać z Twojego sklepu Redux
  • ogień działań ze swoich pojemników.
  • Twoje działania nazywają twoi apis
  • Wynik swoim działaniem aktualizuje sklepu poprzez reduktor
  • Wy pojemniki czytania magazynu przez funkcję mapStateToProps i tak szybko, jak zmienia się wartość w sklepie aktualizuje swój składnik.

Teraz rozważmy Twój przykład todo

TodoListContainer.js

class TodoListContainer extends Component { 

    componentWillMount() { 
    // fire you action action 
    } 


    render() { 
    return (
     <Todos todos=={this.props.todos} /> 
    ) 
    } 
} 


function mapStateToProps(state) { 
    const {todos} = state; 
    return { 
    todos; 
    } 
} 

export default connect(mapStateToProps)(TodoListContainer) 

TodoList.js

class TodoList extends Component { 

    renderTodos() { 
    return this.props.todos.map((todo)=>{ 
     return <Todo todo={todo} key={todo.id} /> 
    }) 
    } 

    render() { 
    return() { 
     if (this.props.todos.length === 0) { 
     return <div>No todos</div> 
     } 
     return (
     <div> 
      {this.renderTodos()} 
     </div> 
    ) 
    } 
    } 
} 

export default class TodoList 

Todo.js

class Todo extends Component { 

    render() { 
    return (
     <div> 
     <span>{this.props.todo.id}</span> 
     <span>{this.props.todo.name}</span> 
     </div> 
    ) 
    } 
} 

Reduktor

export default function todos(state={},action) { 
    switch (action.type) { 
    case 'RECEIVE_TODOS': 
     return Object.assign(state,action.todos); 
    } 
} 

działanie

function fetchTodos() { 
    return(dispatch) => { 
     axios.get({ 
    //api details 
    }) 
    .then((res)=>{ 
     dispatch(receiveTodos(res.todos)) 
    }) 
    .catch((err)=>{ 
     console.warn(err) 
    }) 
    } 
} 

function receiveTodos(todos) { 
    return { 
    type: 'RECEIVE_TODOS', 
    todos 
    } 
} 

Teraz, jeśli przeczytałeś redux dokumentację można zobaczyć, że działania powrócić obiekty potem jak nazwałbym tam moje API, które zwraca funkcję zamiast obiektu. Do tego użyłem redux thunk, o którym można przeczytać here.

Podałem przykład, w którym można pobrać todos. Jeśli chcesz wykonywać inne operacje, takie jak deleteTodo, addTodo, modifyTodo, możesz to zrobić w odpowiednich komponentach.

  1. DeleteTodo - można to zrobić w TodoListContainer.
  2. AddingTodo - możesz to zrobić w TodoListContainer.
  3. Zmiana stanu (zakończona/oczekująca) - można to zrobić w TodoListContainer.
  4. ModifyingTodo - możesz to zrobić w TodoContainer.

Można również sprawdzić here do szczegółowego przykładu, ale przed tym chciałbym powiedzieć tylko powinien przejść podstawami Redux które można znaleźć here

PS: Napisałem kod w locie więc to może nie działa poprawnie, ale powinno działać z niewielkimi modyfikacjami.