4

So, before using material UI, my code was like this. To implement edit feature for ToDo app I used ref from textarea for get current (default) value in there, and then save updated value in save () method (don't worry about editItem method, it is in another component, and I believe there is no need to post him, because the problem is not there)

import React, {Component} from 'react';
import './ToDoItem.css';
import EditButton from './EditButton';
import DeleteButton from './DeleteButton';
import SaveButton from './SaveButton';
import EditToDoField from './EditToDoField';

class ToDoItem extends Component {
    constructor(props) {
        super(props);
        this.state = {
            editMode: false,
        }
      };

      edit = () => {
        this.setState ({editMode: true});
      };

      save = () => {
        let updToDo = this.refs.newToDo.value;
        this.props.editItem (updToDo);

        this.setState ({
          editMode: false})
      };

      renderNormal = () => {
        return (
            <div className="ToDoItem">
            <p className="ToDoItem-Text">{this.props.todo}</p>
            <EditButton editHandler={this.edit} />
        </div>
        );
      };

      renderEdit = () => {
        return (
          <div className="ToDoItem">
            <textarea ref="newToDo" defaultValue={this.props.todo}></textarea>
            <SaveButton saveHandler={this.save} /> 
          </div>
        );
      };

      render() {
        if (this.state.editMode) {
          return this.renderEdit ();
        } else {
          return this.renderNormal ();
        }
      }
}

export default ToDoItem;

So, now I trying to implement beautiful TextField from material UI, texarea tag was deleted and here is the respective additions to code:

<EditToDoField 
                ref="newToDo"
                defaultToDoValue={this.props.todo} 
            />

and EditToDoField component:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  textField: {
    marginLeft: theme.spacing.unit,
    marginRight: "61px",
  },
});

class OutlinedTextFields extends React.Component {

  render() {
    const { classes } = this.props;

    return (
      <form className={classes.container} noValidate autoComplete="off">
        <TextField
          id="outlined-editToDO"
          label="Edit ToDo"
          defaultValue={this.props.defaultToDoValue}
          className={classes.textField}
          multiline
          margin="normal"
          variant="outlined"
        />
      </form>
    );
  }
}

OutlinedTextFields.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(OutlinedTextFields);

So I pass current (default) value to EditToDoField, but when I'm trying to save updated ToDo text, I got empty field in result. I understand that most probably I just missed something, but still don't get what. I also tried to use "innerRef" and "inputRef" instead of "ref", but no luck. Can you please help me with this stuff ?

4
  • Any luck with my answer? Commented Sep 29, 2018 at 18:35
  • Input works, values from console.log appears as it should, but I still have empty field after saving edited input ... Commented Sep 29, 2018 at 18:59
  • See my updated answer. Commented Sep 29, 2018 at 19:12
  • It seems to work, according to console, but I still don't understand how to implement it inside my exact code. I must continue after some sleep ... Commented Sep 29, 2018 at 19:50

1 Answer 1

2

Add a simple event handler when the user enters text, you can then use a callback to move the input from the text field to whatever component you want, here's the full example

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap'
  },
  textField: {
    marginLeft: theme.spacing.unit,
    marginRight: '61px'
  }
});

class OutlinedTextFields extends React.Component {
  handleOnChange = event => {
    console.log('Click');
    console.log(event.target.value);
  };

  render() {
    const { classes } = this.props;

    return (
      <form className={classes.container} noValidate autoComplete="off">
        <TextField
          id="outlined-editToDO"
          label="Edit ToDo"
          defaultValue={this.props.defaultToDoValue}
          className={classes.textField}
          multiline
          margin="normal"
          variant="outlined"
          onChange={this.handleOnChange}
        />
      </form>
    );
  }
}

OutlinedTextFields.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(styles)(OutlinedTextFields);
Sign up to request clarification or add additional context in comments.

6 Comments

Hm, I also can simply get the value by using inputRef: <TextField inputRef={el => this.ToDoRef = el} /> handleOnChange = event => { console.log(this.ToDoRef.value); }; Just need to send this value to my save () method in ToDoItem component ...
You don't need to use references.
Paul, thank you, I finally got your point, everything works now ! Well, almost everything. I still got a problem. If I hit edit button and don't change the input text, and then hit save button, then I got empty field as a result. So I need to actually change the field, if I tried to save the same input, I got empty field. How to solve this "bug" ? And take a look at my updated code please: codesandbox.io/s/01w2v171vn
I believe I solved it, check codesandbox. And cat you please explain what event.preventDefault(); function do ?
Ok, but my button is from material UI, not default one from HTML, so I can delete this function. Thank you once again )
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.