如何使用React创建一个“类似”的剩余字符

时间:2015-10-12 10:46:10

标签: javascript twitter-bootstrap twitter reactjs reactive-programming

我正在寻找与#34;目标人物数量相关的反应计数器"对于像Twitter一样的textarea,随着用户的输入而减少。

例如,在"元描述"字段,目标字符数为160.因此,如果字段为空,则数字为160.当用户键入时,计数减少,每个字符添加到输入字段,直到达到零。

如果计数高于目标,则数字将以红色写入,前面带有减号(再次,就像推特一样)。

执行此操作的一种方法是在textarea上侦听onChange事件,并更新组件的状态(具有textarea和计数器),然后使用它来计算长度并渲染剩余的char计数器。

有更有效的方法吗?

4 个答案:

答案 0 :(得分:8)

这是您想要的粗略版本。当chars_left低于零时不处理,但应该易于实现。

var TwitterInput = React.createClass({
    getInitialState: function() {
        return {
            chars_left: max_chars
        };
    },
    handleChange(event) {
        var input = event.target.value;
        this.setState({
            chars_left: max_chars - input.length
        });
    },
    render: function() {
        return (
            <div>
                <textarea onChange={this.handleChange.bind(this)}></textarea>
                <p>Characters Left: {this.state.chars_left}</p>
            </div>
        );
    }
});

https://jsfiddle.net/terda12/b0y4jL6t

答案 1 :(得分:1)

我也做了一个版本,

我正在使用样式组件进行样式设计。

"build": "rimraf dist && node --max-old-space-size=8192 node_modules\\.bin\\webpack --config config/webpack.prod.js --progress --profile --bail"

在表单中:

import React from "react";
import styled from "styled-components";

class CharCountInput extends React.Component {
  state = {
    charsLeft: null
  };

  componentDidMount() {
    this.handleCharCount(this.props.value);
  }

  handleCharCount = value => {
    const { maxChars } = this.props;
    const charCount = value.length;
    const charsLeft = maxChars - charCount;
    this.setState({ charsLeft });
  };

  handleChange = event => {
    this.handleCharCount(event.target.value);
    this.props.onChange(event);
  };

  renderCharactersLeft = () => {
    const { charsLeft } = this.state;

    let content;
    if (charsLeft >= 0) {
      content = <SpanOK>{`characters left: ${charsLeft}`}</SpanOK>;
    } else if (charsLeft != null && charsLeft < 0) {
      const string = charsLeft.toString().substring(1);
      content = <SpanError>{`too many characters: ${string}`}</SpanError>;
    } else {
      content = null;
    }
    return content;
  };

  render() {
    const { onBlur, value, type, name, placeholder } = this.props;

    return (
      <Div>
        <Input
          onChange={this.handleChange}
          value={value}
          type={type}
          name={name}
          placeholder={placeholder}
        />
        {this.renderCharactersLeft()}
      </Div>
    );
  }
}

export default CharCountInput;

const Div = styled.div`
  display: flex;
  flex-direction: column;
`;

const Input = styled.input`
  box-sizing: border-box;
  display: block;
  padding: 7px;
  width: 100%;
  margin: 0 0 0.1rem 0;
  border: 1px solid blue;
  border-radius: 7px;
  font: inherit;
  outline: none;

  &:focus {
    box-shadow: 0 0 4px blue;
  }
`;

const Span = styled.span`
  align-self: flex-end;
  font-size: 0.9rem;
  margin: 0 8px 10px 0;
`;

const SpanOK = styled(Span)`
  color: black;
`;

const SpanError = styled(Span)`
  color: red;
`;

答案 2 :(得分:0)

var TwitterInput = React.createClass({
    getInitialState: function() {
        return {
            chars_left: max_chars
        };
    },
    handleChange(event) {
        var input = event.target.value;
        this.setState({
            chars_left: max_chars - input.length
        });
    },
    render: function() {
        return (
            <div>
                <textarea onChange={this.handleChange.bind(this)}></textarea>
                <p>Characters Left: {this.state.chars_left}</p>
            </div>
        );
    }
});  

以上来自Keith Young的答案非常有效(为我的react应用调整了一些)。要添加最大字符数的设置限制,以免出现负数,只需添加     maxlength={max_chars} 到textarea元素。

答案 3 :(得分:0)

这里是React Native方式,但您也可以在react.js中使用此方法

//your state
constructor() {
    super();
    this.state = {
        chars_left: 500,
        chars_exceed: false,
        post_text: ''
    };
};

//handle change function 
handleChange(text) {
    this.setState({
        chars_left: text.length,
        chars_exceed: text.length >  500  ?  true  :  false,
        post_text: text,
    });
}

//input inside render
render() { 
    return (
        <View>
            //text area
            <Textarea 
                rowSpan={10} 
                value={this.state.post_text}
                onChangeText={this.handleChange.bind(this)}
                placeholder="Type here"/>
            //text balance count
            <Text>{ this.state.chars_left }/500</Text>
        </View>
    )
}