Как бы я сохранил текст в состоянии, которое пользователь написал с помощью Redux? - PullRequest
0 голосов
/ 24 сентября 2018

Всякий раз, когда пользователь вводит что-то в <textarea> и затем нажимает submit, я хочу отобразить то, что он написал в функции alert() через handleStorytext().

Как мне этого добиться и что я сделал не так?

На данный момент, после записи чего-либо в <textarea> и затем нажатия submit, я получаю ошибку, которая указывает на handleStorytext() высказывание: TypeError: Cannot read property 'setState' of undefined.

Вот CreateArticle:

import React, { Component } from 'react';
import {connect} from "react-redux";
import * as actionType from "../../store/actions/actions";

class CreateArticle extends Component {
    constructor(props) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({value: event.target.value});
        this.props.articleIdValueRedux(event.target.value);
    }

    handleSubmit(event) {
        this.setState({value: event.target.value});
        this.props.storyTextValueRedux(event.target.value);
        event.preventDefault();
    }

    handleStoryText(event) {
        this.setState({value: event.target.value});
        this.props.storyTextValueRedux(event.target.value);
        alert("Article saved " + '\n' + this.props.storyTextValue);
        event.preventDefault();
    }

    render() {
        return(
            <div>
                <form onSubmit={this.handleSubmit}>
                    <input onChange={this.handleChange} value={this.props.cityCodeValue} type="text" placeholder="city code"/>
                    <input type="text" placeholder="author name"/>
                    <textarea value={this.props.storyTextValue} onChange={this.handleStoryText} rows="2" cols="25" />
                    <input type="submit" value="Submit"/>
                </form>
            </div>
        );
    }
}

const mapStateToProps = state => {
    return {
        articleIdValue: state.articleIdValue.articleIdValue,
        storyTextValue: state.storyTextValue.storyTextValue
    };
};

const mapDispatchToProps = dispatch => {
    return {
        articleIdValueRedux: (value) => dispatch({type: actionType.ARTICLE_ID_VALUE, value}),
        storyTextValueRedux: (value) => dispatch({type: actionType.STORY_VALUE, value})

    };
};

export default connect(mapStateToProps, mapDispatchToProps)(CreateArticle);

Вот ArticleIdReducer:

import * as actionType from '../store/actions/actions';

const initialState = {
    storyTextValue: ''
};

const StoryTextReducer = (state = initialState, action) => {
    switch (action.type) {
        case actionType.STORY_VALUE:
            return {
                ...state,
                storyTextValue: action.value
            };
        default:
            return state;
    }
};

export default StoryTextReducer;

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Мало что вы делаете неправильно

  1. Вы используете функцию в textarea onChange, но не привязываете ее.Вам нужно всегда связывать его в конструкторе и никогда не связывать функцию напрямую в рендере или где-либо еще, кроме конструктора
  2. . Вам нужно присвоить this.state.value для значения prop в textarea, но вы назначаете prop, которая не 't существует
  3. Также, когда вы устанавливаете setState, обновленное значение состояния не будет доступно непосредственно перед рендерингом

Приведенный ниже код работает для вас в ES5

import React, { Component } from 'react';
import {connect} from "react-redux";
import * as actionType from "../../store/actions/actions";

class CreateArticle extends Component {
    constructor(props) {
        super(props);
        this.state = {
           value: "",
           error: ""
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleStoryText = this.handleStoryText.bind(this);
    }

    handleChange(event) {
        this.setState({value: event.target.value});
        this.props.articleIdValueRedux(event.target.value);
    }

    handleSubmit(event) {
        this.setState({value: event.target.value});
        this.props.storyTextValueRedux(event.target.value);
        event.preventDefault();
    }

    handleStoryText(event) {
        event.preventDefault();
        this.setState({value: event.target.value});

    }
    onSubmit = () => {
       if(this.state.value === ""){
          alert("Please enter the value and then click submit");
       }else{
           alert("Article saved " + '\n' + this.state.value);
       }
    }
    render() {
        const { value } = this.state;
        return(
            <div>
                <form onSubmit={this.handleSubmit}>
                    <input onChange={this.handleChange} value={this.props.cityCodeValue} type="text" placeholder="city code"/>
                    <input type="text" placeholder="author name"/>
                    <textarea value={value} onChange={this.handleStoryText} rows="2" cols="25" />
                    <input type="submit" value="Submit" onclick={this.onSubmit}/>
                </form>
            </div>
        );
    }
}

const mapStateToProps = state => {
    return {
        articleIdValue: state.articleIdValue.articleIdValue,
        storyTextValue: state.storyTextValue.storyTextValue
    };
};

const mapDispatchToProps = dispatch => {
    return {
        articleIdValueRedux: (value) => dispatch({type: actionType.ARTICLE_ID_VALUE, value}),
        storyTextValueRedux: (value) => dispatch({type: actionType.STORY_VALUE, value})

    };
};

export default connect(mapStateToProps, mapDispatchToProps)(CreateArticle);

Если вы не любите делать привязки в конструкторе, используйте функции стрелок.Преимущество функции стрелка в том, что вам не нужно связывать функцию и не нужно ссылаться на локальную переменную, например, self, например.этот контекст по умолчанию доступен в функции стрелки

Код версии ES6

import React, { Component } from 'react';
import {connect} from "react-redux";
import * as actionType from "../../store/actions/actions";

class CreateArticle extends Component {
    constructor(props) {
        super(props);
        this.state = {
           value: ""
        }
    }

    handleChange = event => {
        this.setState({value: event.target.value});
        this.props.articleIdValueRedux(event.target.value);
    }

    handleSubmit = event => {
        event.preventDefault();
        this.setState({value: event.target.value});
        this.props.storyTextValueRedux(event.target.value);   
    }

    handleStoryText = event => {
        event.preventDefault();
        this.setState({value: event.target.value});

    }

    onSubmit = () => {
       if(this.state.value === ""){
          alert("Please enter the value and then click submit");
       }else{
           alert("Article saved " + '\n' + this.state.value);
       }
    }

    render() {
        const { value } = this.state;
        return(
            <div>

                <form onSubmit={this.handleSubmit}>
                    <input onChange={this.handleChange} value={this.props.cityCodeValue} type="text" placeholder="city code"/>
                    <input type="text" placeholder="author name"/>
                    <textarea value={value} onChange={this.handleStoryText} rows="2" cols="25" />
                    <input type="submit" value="Submit" onclick={this.onSubmit}/>
                </form>
            </div>
        );
    }
}

const mapStateToProps = state => {
    return {
        articleIdValue: state.articleIdValue.articleIdValue,
        storyTextValue: state.storyTextValue.storyTextValue
    };
};

const mapDispatchToProps = dispatch => {
    return {
        articleIdValueRedux: (value) => dispatch({type: actionType.ARTICLE_ID_VALUE, value}),
        storyTextValueRedux: (value) => dispatch({type: actionType.STORY_VALUE, value})

    };
};

export default connect(mapStateToProps, mapDispatchToProps)(CreateArticle);
0 голосов
/ 24 сентября 2018

при передаче функций-обработчиков onChange область действия 'this' теряется.

Итак, используйте onChange={this.handleStoryText.bind(this)} в функции рендеринга

Для получения дополнительной информацииВы можете проверить эти документы

  import React, { Component } from 'react'; import {connect} from
    "react-redux"; import * as actionType from
    "../../store/actions/actions";

    class CreateArticle extends Component {
        constructor(props) {
            super(props);
            this.state = {storyTextValue:""}
            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
        }

        handleChange(event) {
            this.setState({value: event.target.value});
            this.props.articleIdValueRedux(event.target.value);
        }

        handleSubmit(event) {
            this.setState({value: event.target.value});
            this.props.storyTextValueRedux(event.target.value);
              alert("Article saved " + '\n' + this.state.storyTextValue);
            event.preventDefault();
        }

        handleStoryText(event) {
            this.setState({storyTextValue: event.target.value});
            this.props.storyTextValueRedux(event.target.value);
            event.preventDefault();
        }

        render() {
            return(
                <div>
                    <form onSubmit={this.handleSubmit.bind(this)}>
                        <input onChange={this.handleChange} value={this.props.cityCodeValue} type="text" placeholder="city code"/>
                        <input type="text" placeholder="author name"/>
                        <textarea value={this.props.storyTextValue} onChange={this.handleStoryText} rows="2" cols="25" />
                        <input type="submit" value="Submit"/>
                    </form>
                </div>
            );
        } }

    const mapStateToProps = state => {
        return {
            articleIdValue: state.articleIdValue.articleIdValue,
            storyTextValue: state.storyTextValue.storyTextValue
        }; };

    const mapDispatchToProps = dispatch => {
        return {
             articleIdValueRedux: (value) => dispatch({type: actionType.ARTICLE_ID_VALUE, value}),
             storyTextValueRedux: (value) => dispatch({type: actionType.STORY_VALUE, value})

         }; };

     export default connect(mapStateToProps,
     mapDispatchToProps)(CreateArticle)

;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...