问题
I am creating an SPFX form (react/Typescript). I am using a handler function:
public handleChange = (evt: any) => {
const {value} = (evt.target as any);
this.setState({
...this.state,
[evt.target.name]: value
});
}
To handle multiple text fields.
What I want to do now is for this handler to cater for character count text fields. (I know I could have used labels!) These text fields count how many characters have been entered into each text field. I don't know how to write the code for this. Below is what I've tried:
The handler function:
public handleChange = (evt: any) => {
const {value} = (evt.target as any);
this.setState({
...this.state,
[evt.target.name]: value
}, () => {
let wordCount = this.state.SOMETHING.toString().length; //This is wrong!
this.setState({
...this.state,
[evt.target.name]: wordCount
});
});
}
But as you can see I'm way off understanding what to put. As you can see with wordCount
variable, I'm counting the amount of characters for the state of a textfield but this is obviously not going to work because I need it to cater for ALL of the textfields that run through the handler function. You can see also that I'm attempting to set this to state using the [evt.target.name]: wordCount
, this I think is possibly closer to being correct. But not sure.
And if it helps, here are 2 textfields, one which is the user input text field and the other (below it) is the character counter:
<td><TextField
name="EssCrit1"
value={this.state.EssCrit1}
onChange={this.handleChange}
multiline rows={2}
/>
</td>
<td ><TextField
name="EssCritChars1"
value={this.state.EssCritChars1}
disabled={true}
/>
</td>
As you can see the character counter has it's own state but as mentioned above, how do i get the handler function to cater for that as well as the onChange event for the user input text field?
Any help would be great as always.
C
回答1:
If you want to handle any given text field's value and the value's length:
public handleChange = (evt: any) => {
const {value} = (evt.target as any);
this.setState({
[evt.target.name]: value,
`${evt.target.name}Count`: value.toString.length,
});
}
回答2:
If I'm understanding correctly, you could curry and add an additional parameter with the name of the corresponding counter to your onChange like this:
<TextField
name="EssCrit1"
value={this.state.EssCrit1}
onChange={this.handleChange('EssCritChars1')} // curry the name of the counter like this
multiline rows={2}
/>
// We'll use counterName to update the correct counter state value
handleChange = (counterName: string) => (evt: any) => {
const {value} = (evt.target as any);
this.setState({
[evt.target.name]: value
}, () => {
let wordCount = this.state[evt.target.name].toString().length; // Access as an array to use dynamic keys
this.setState({
[counterName]: wordCount // now we have a separate counter variable
});
});
}
Or, you could use an inline function with an optional second parameter like this:
// Text field that has a counter
<TextField
name="EssCrit1"
value={this.state.EssCrit1}
onChange={(e) => this.handleChange(e, 'EssCritChars1')} // Inline. Pass event and name of counter
multiline rows={2}
/>
// Text field that doesn't need a counter
<TextField
name="another_field"
value={this.state.another_field}
onChange={this.handleChange} // We only need the event so don't bother creating an inline function
multiline rows={2}
/>
// Second param is optional
handleChange = (evt: any, counter = '') => {
const {value} = (evt.target as any);
let newState = {
[evt.target.name]: value
}
if (counter) {
newState[counter] = value.toString().length
}
this.setState(prevState => ({...prevState, newState });
}
来源:https://stackoverflow.com/questions/59649296/how-to-use-a-handler-function-for-two-different-purposes-spfx-react-typescript