文本区显示不正确的字符数在ReactJS



我有一个文本区,我在底部显示字符计数。我正在传递API作为道具的响应,因为我想显示字符计数。我的onChange函数工作正常,我没有传递数据作为道具。当我在useEffect的帮助下得到API响应时,我正在更新我的组件。

但是我正面临计数的问题,它显示计数不正确。我已经附上了React组件的代码片段。

class TextAreaComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
characterCount: '1500'
};
}
handleWordCount = (e) => {
const charCount = e.target.value.length;
const maxCharCount = e.target.getAttribute("max-length");
const charLeft = maxCharCount - charCount;
this.setState({
characterCount: charLeft
});
}
render() {
const { data } = this.props;
// Binding the data in value,
return (
<div className="personal-bio">
<h4>Bio</h4>
<textarea onChange={this.handleWordCount} value={data && data.length > 0 ? data : ""} max-length="1500" name="textarea" placeholder="Tell me about yourself"></textarea>
<p className="user-bio-char-limit">Total Character limit : {this.state.characterCount}</p>
</div>
)
}
}
// Passing the response data as props
ReactDOM.render(
<TextAreaComponent data="Hello, this is my bio" />, document.body
);
textarea {
border: 1px solid #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

这里有两个问题。首先,您没有在更改时更新textarea值。第二个问题是,当结果来自API时,你也必须计算计数。你可以在componentDidUpdate生命周期函数中完成这项工作,但因为我无法访问API,所以我将使用componentDidMount来显示你应该做什么。

class TextAreaComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
characterCount: '1500',
data: ""
};
}
componentDidMount() {
const charCount = this.props.data.length;
const maxCharCount = this.state.characterCount;
const charLeft = maxCharCount - charCount;
this.setState({
characterCount: charLeft,
data: this.props.data
});
}
handleWordCount = (e) => {
const charCount = e.target.value.length;
const maxCharCount = e.target.getAttribute("max-length");
const charLeft = maxCharCount - charCount;
this.setState({
characterCount: charLeft,
data: e.target.value
});
}
render() {
const { data } = this.state;
// Binding the data in value,
return (
<div className="personal-bio">
<h4>Bio</h4>
<textarea onChange={this.handleWordCount} value={data && data.length > 0 ? data : ""} max-length="1500" name="textarea" placeholder="Tell me about yourself"></textarea>
<p className="user-bio-char-limit">Total Character limit : {this.state.characterCount}</p>
</div>
)
}
}
// Passing the response data as props
ReactDOM.render(
<TextAreaComponent data="Hello, this is my bio" />, document.body
);
textarea {
border: 1px solid #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

字符数最初是错误的,因为您将其硬编码为1500而不是1500 - props.data.length。也就是说,this.state.characterCount似乎是一个计算值,没有必要将其存储在状态中。我建议将value存储在状态中,因为这是实际更改的部分。然后,您可以在组件的呈现部分中直接计算剩余的字符。下面是一个简化的功能组件:

const MAX_LENGTH = 1500;
const TextAreaComponent = ({ data }) => {
// Set the value of `data` as the initial value of the textarea.
const [value, setValue] = useState(data);
return (
<div className="personal-bio">
<h4>Bio</h4>
<textarea
max-length={MAX_LENGTH}
name="textarea"
onChange={(e) => setValue(e.target.value)}
placeholder="Tell me about yourself"
value={value}
/>
<p className="user-bio-char-limit">
Remaining characters: {MAX_LENGTH - value.length}
</p>
</div>
);
};

工作沙箱:https://codesandbox.io/s/ecstatic-poitras-8gbwd

更新:下面是一个状态完全由父进程控制的例子。要简单得多,因为Textarea组件只需响应道具的更改,而不必同步状态和道具。

const TextAreaComponent = ({ data, onChange }) => (
<div className="personal-bio">
<h4>Bio</h4>
<textarea
max-length={MAX_LENGTH}
name="textarea"
onChange={onChange}
placeholder="Tell me about yourself"
value={data}
/>
<p className="user-bio-char-limit">
Remaining characters: {MAX_LENGTH - data.length}
</p>
</div>
);
const Parent = () => {
const [data, setData] = useState('Hello, this is my bio');
useEffect(() => {
// Make your API call here and update state using `setData`
// when the request finishes.
}, []);
return (
<TextAreaComponent data={data} onChange={(e) => setData(e.target.value)} />
);
};

最新更新