如何将文本存储在用户使用Redux编写的状态中?

问题描述 投票:2回答:2

每当用户在<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;
javascript reactjs debugging redux react-redux
2个回答
1
投票

你做的事情很少不正确

  1. 您正在使用textarea onChange中的函数,但您没有绑定它。您需要始终在构造函数中绑定它,并且永远不要直接在渲染中或除构造函数之外的任何其他位置绑定函数
  2. 你需要将this.state.value分配给textarea中的prop prop,但是你要分配一个不存在的prop
  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
投票

当你传递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)

;
© www.soinside.com 2019 - 2024. All rights reserved.