我如何在用户使用Redux编写状态下存储文本?

时间:2018-09-24 11:28:01

标签: javascript reactjs debugging redux react-redux

每当用户在<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 :(得分:1)

您所做的一些错误操作

  1. 您正在textarea onChange中使用函数,但未绑定它。您 需要始终在构造函数中绑定它,而从不绑定函数 直接在渲染器中或除构造函数之外的其他任何地方
  2. 您需要将this.state.value分配给textarea中的value道具,但您要分配的道具不存在
  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);

答案 1 :(得分:0)

当您传递onChange处理函数时,“ this”的范围将丢失。

  

因此,在渲染中使用onChange={this.handleStoryText.bind(this)}   功能

有关更多信息,您可以检查这些docs

  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)

;