Laura delgado
Laura delgado

Reputation: 362

Reactjs Concat with prev state

I have this simple react code

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      textarea: 'Hello World! \n \nTry to press Shift enter after Hello \n \nShould be like this \nHello \nWorld! '
    };
  }
  onChange = (e) => {
    this.setState({ textarea: e.target.value })
  }
  handlePress = e => {
    if (e.keyCode === 13 && e.shiftKey) {
      e.preventDefault();
      this.setState(prevState => ({ textarea: prevState.textarea.concat('\n why here') }))
    } else if (e.keyCode === 13) {
      e.preventDefault();

    }
  }
  render() {
    return (
      <div>

        <textarea style={{ height: 200, width: 200 }} value={this.state.textarea} onKeyDown={this.handlePress} onChange={this.onChange} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('code'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='code'></div>

enter image description here

Should Be like this

enter image description here

Can anyone help me please or just guide me to correct way I'm stack in this problem even I don't know how to explain it to make a research

Upvotes: 1

Views: 11593

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281626

You can make use of selectionStart value to get cursor position and break the text at that position and use .slice method to set the value back to state after appending \n;

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      textarea: 'Hello World! \n \nTry to press Shift enter after Hello \n \nShould be like this \nHello \nWorld! '
    };
  }
  onChange = (e) => {
    this.setState({ textarea: e.target.value })
  }
  handlePress = e => {
    e.persist();
    if (e.keyCode === 13 && e.shiftKey) {
      e.preventDefault();
      const pos = e.target.selectionStart;
      console.log(this.state.textarea)
      this.setState(prevState => ({ textarea: prevState.textarea.slice(0, pos) + " \n " + prevState.textarea.slice(pos) }))
    } else if (e.keyCode === 13) {
      e.preventDefault();

    }
  }
  render() {
    return (
      <div>

        <textarea style={{ height: 200, width: 200 }} value={this.state.textarea} onKeyDown={this.handlePress} onChange={this.onChange} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('code'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='code'></div>

Upvotes: 1

catchergeese
catchergeese

Reputation: 732

In this fragment of your code:

this.setState(prevState => ({ textarea: prevState.textarea.concat('\n why here') }))

you concat the previous textarea state with some string - in your case "\n why here". It joins the end of the former string with the beginning of the latter - nothing more, nothing less.

As you see, there is no notion of a cursor in your code - you don't specify correctly where "\n why here" should be put.

Please have a look at selectionStart (and maybe selectionEnd) to get cursor's position.

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Property/selectionStart

Then, change the concat part of your logic to insert your string in desired position.

Upvotes: 3

Related Questions