F
F
fierfoxik2017-06-17 16:17:08
React
fierfoxik, 2017-06-17 16:17:08

How to properly pass action to reducer from component?

No matter how much I read the documentation, I still can’t figure out how to correctly dispatch actions with data or how to properly accept them in the Reducer.
As I understand it, I only need to somehow pass it to the actions reducer in which my data will fall.
And for example, they threw me a code with this and ref attributes in the component, I still didn’t understand what this was for and why null was falling into this.
To be honest, I’m already confused in the edge and my hands are starting to fall from the fact that I can’t do a simple thing, if someone can thoroughly explain I would be very grateful.
action

export const addItem = (book) => { return { type: 'BUTTON_CLICK',book} }

reducer
export default function rootReducer(state = [], action) {
    console.log(action);
    if(action.type === 'BUTTON_CLICK'){
        return[
        ...state,
            action.book
        ]
            store.dispatch(state)
    }
    return state;
}

Component
import React, { Component } from 'react';
import { dispatch } from 'redux'
import addItem from '../actions/userActions'
import rootReducer from '../reducers/reducers'

export default class Inputs extends Component {
    render() {
function takeVal() {
    console.log(this)
    const name = this.inputName.value;
    const author = this.inputAuthor.value;

    rootReducer.dispatch(addItem(author, name));

    // для очистки инпутов
    this.inputName.value = '';
    this.inputAuthor.value = '';
}
        return (
            <div className="app__enter">
                <div className="inputs-bock">
                    <input className="inputs-book__author" placeholder="Автор" ref={ (input) => this.inputAuthor = input } type="text"/>
                    <input className="inputs-book__name" placeholder="Название" ref={ (input) => this.inputName = input } type="text"/>
                </div>
                <div className="button-wrap">
                    <button onClick={takeVal}>Добавить книгу</button>
                </div>
            </div>
        )
    }
}

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Maxim, 2017-06-17
@fierfoxik

export default function rootReducer(state = [], action) {
    console.log(action);
    if(action.type === 'BUTTON_CLICK'){
        return[
        ...state,
            action.book
        ]
            store.dispatch(state) // выкинуть отсюда.
    }
    return state;
}

In the component, use state, store name and author in it. On button click, you need to call ACTION. Most likely, it will come to you from the parent container (the component that is attached to the store using the connect function).
Inputs can be rewritten like this:
export default class Inputs extends Component {
    constructor(props) {
        super(props)
        this.onAuthorChange = this.onAuthorChange.bind(this)
        this.onNameChange = this.onNameChange.bind(this)
        this.takeVal = this.this.takeVal.bind(this)
        this.state = {
            author: '',
            name: '',
        }
    }
    onAuthorChange(e) {
        this.setState({ author: e.target.value })
    }
    onNameChange(e) {
        this.setState({ name: e.target.value })
    }
    takeVal() {
        this.props.addItem({ // имя, под которым вы передали свой экшен в качестве пропса от родителя
            author: this.state.author,
            name: this.state.name,
        })
    }
    render() {
        const {author, name} = this.state
        return (
            <div className="app__enter">
                <div className="inputs-bock">
                    <input onChange={this.onAuthorChange} className="inputs-book__author" placeholder="Автор" type="text" value={author}/>
                    <input onChange={this.onNameChange} className="inputs-book__name" placeholder="Название" type="text" value={name}/>
                </div>
                <div className="button-wrap">
                    <button onClick={this.takeVal}>Добавить книгу</button>
                </div>
            </div>
        )
    }
}

Of course, since the onAuthorChange and onNameChange function code is the same, it can be fit (and very easily) in one function...
Your "attached parent" might look like this:
import React, { Component } from 'react'
import Inputs from '../components/Inputs'
import { connect } from 'react-redux'

import {
  addItem,
} from '../../actions/UserActions'

class InputsContainer extends Component {
  render() {
    return <Inputs addItem={this.props.addItem} />
  }
}

const mapStateToProps = (state) => ({})

const mapDispatchToProps = (dispatch) => ({
  addItem: (params) => dispatch(addItem(params)),
})

export default connect(mapStateToProps, mapDispatchToProps)(InputsContainer)

ps docks need to be read, I support. DZ: Rename addItem in props and call it inside takeVal. Make one out of 2 functions of change handlers in inputs.

V
Vitaly, 2017-06-17
@vshvydky

It’s immediately obvious that you don’t read the docks, and therefore the advice is simple, read the dock from cover to cover in redax, there is a Russian translation.

R
Roman Alexandrovich, 2017-06-18
@RomReed

Documentation: https://rajdee.gitbooks.io/redux-in-russian/conten...
There are simple examples. Download it and play around until you figure out how it works.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question