React中为何无法通过Material-UI按钮修改父组件状态?新手计算器开发遇困
Hey there! Let's get your calculator set up to track input as a string in the parent component's state. Since you're using class components and Material-UI's RaisedButton, here's a complete, working implementation tailored to your needs:
Step 1: Initialize State in the Parent Component
First, we'll set up a state property to hold the input string (numbers + operators). In your Calc class, initialize the state with an empty string:
import React, { Component } from 'react'; import RaisedButton from 'material-ui/RaisedButton'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; class Calc extends Component { constructor(props) { super(props); // Initialize state to store the input string this.state = { input: '' }; // Bind the handler method to ensure correct `this` context this.handleButtonClick = this.handleButtonClick.bind(this); }
Step 2: Create a Click Handler to Update State
Next, add a method that appends the clicked button's value to the state's input string. This method will be passed to each RaisedButton as the onClick handler:
handleButtonClick(value) { // Update state by appending the clicked value to the existing input this.setState(prevState => ({ input: prevState.input + value })); }
Step 3: Render Material-UI Buttons with the Handler
Now, render your calculator buttons wrapped in MuiThemeProvider (required for Material-UI styles to work). Each button will call handleButtonClick with its corresponding value:
render() { return ( <MuiThemeProvider> <div style={{ padding: '20px', maxWidth: '300px', margin: '0 auto' }}> {/* Display the current input string */} <div style={{ padding: '10px', marginBottom: '15px', border: '1px solid #ddd', textAlign: 'right', fontSize: '1.5rem' }}> {this.state.input || '0'} </div> {/* Number buttons */} <div style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}> <RaisedButton label="7" onClick={() => this.handleButtonClick('7')} /> <RaisedButton label="8" onClick={() => this.handleButtonClick('8')} /> <RaisedButton label="9" onClick={() => this.handleButtonClick('9')} /> </div> <div style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}> <RaisedButton label="4" onClick={() => this.handleButtonClick('4')} /> <RaisedButton label="5" onClick={() => this.handleButtonClick('5')} /> <RaisedButton label="6" onClick={() => this.handleButtonClick('6')} /> </div> <div style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}> <RaisedButton label="1" onClick={() => this.handleButtonClick('1')} /> <RaisedButton label="2" onClick={() => this.handleButtonClick('2')} /> <RaisedButton label="3" onClick={() => this.handleButtonClick('3')} /> </div> <div style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}> <RaisedButton label="0" onClick={() => this.handleButtonClick('0')} /> <RaisedButton label="." onClick={() => this.handleButtonClick('.')} /> <RaisedButton label="C" onClick={() => this.setState({ input: '' })} /> </div> {/* Operator buttons */} <div style={{ display: 'flex', gap: '10px' }}> <RaisedButton label="+" onClick={() => this.handleButtonClick('+')} /> <RaisedButton label="-" onClick={() => this.handleButtonClick('-')} /> <RaisedButton label="*" onClick={() => this.handleButtonClick('*')} /> <RaisedButton label="mod" onClick={() => this.handleButtonClick('mod')} /> </div> <div style={{ marginTop: '10px' }}> <RaisedButton label="=" primary={true} onClick={() => { // Later, add calculation logic here using this.state.input console.log('Calculating:', this.state.input); }} /> </div> </div> </MuiThemeProvider> ); } } export default Calc;
Key Notes:
- State Updates: We use
setStatewith a function (prevState => ...) to ensure we're always using the latest state value when appending new input—this avoids race conditions if multiple clicks happen quickly. - Context Binding: In the constructor, we bind
handleButtonClicktothisso that the method has access to the component's state when called by the buttons. - Display: We show the current input string in a div (falling back to '0' if the input is empty) so you can see what's being tracked.
- Clear Button: The "C" button resets the input state to an empty string, which is a common calculator feature.
When you click any button, the corresponding value gets added to the input state string. Later, you can parse this string to perform calculations (just be sure to handle edge cases like invalid operator sequences!).
内容的提问来源于stack exchange,提问作者piotr.wolski95

