1

I have three components, App, TextBox and Keyboard.

What I am trying to do is:

  1. User clicks on one of the buttons on keyboard.jsx, a child component
  2. Pass the associated character to App.js (this works, via callback functions)
  3. Once a new character has been passed to App.js, update the other child component, TextBox.jsx, by passing it the new value.

However, I am stuck at step 3. I have the value passed to App.js, but I don't know how to pass it to the child component, Keyboard.jsx, so i can update the input form.

Here is my code:

keyboard.jsx

import React, { Component } from "react";

class Keyboard extends Component {
  state = {
    current: null,
    keys: ["á", "é", "í", "ñ", "ó", "ú", "ü"]
  };

  render() {
    return (
      <div>
        <table>
          <tbody>
            {Object(
              this.state.keys.map(key => {
                return (
                  <td>
                    <button
                      onClick={() => {
                        this.solve(key, this.props.handler);
                      }}
                    >
                      {key}
                    </button>
                  </td>
                );
              })
            )}
          </tbody>
        </table>
      </div>
    );
  }
  solve = (char, callback) => {
    this.setState({ current: char });
    callback(char);
    return;
  };
}

export default Keyboard;

textbox.jsx

import React, { Component } from "react";

class TextBox extends Component {
  state = { equation: null };
  render() {
    return (
      <div>
        <form onSubmit={this.mySubmitHandler}>
          <input
            size="35"
            type="text"
            name="equation"
            onChange={this.handleInputChange}
          />
        </form>
      </div>
    );
  }
  handleInputChange = event => {
    event.preventDefault();
    this.setState({
      [event.target.name]: event.target.value
    });
  };

  mySubmitHandler = event => {
    event.preventDefault();
    this.setState({ equation: event.target.value });
    alert("You are submitting " + this.state.equation);
    console.log(this.state.equation);
  };
}

export default TextBox;

App.js

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import Keyboard from "./components/keyboard";
import TextBox from "./components/textbox";

class App extends Component {
  state = { character: null };
  render() {
    return (
      <div>
        <TextBox />
        <Keyboard handler={this.handler} />
      </div>
    );
  }

  handler = arg => {
    console.log(arg);
  };
}

export default App;
2
  • You don’t seem to be using props? Commented Dec 13, 2019 at 5:33
  • I am not sure what are you doing here, but passing your arg as a prop to TextBox will do the trick Commented Dec 13, 2019 at 5:35

3 Answers 3

1

What I see you are trying to do is to have buttons with certain special letter that you can click to insert them into a input field that is in a separate component.

In this particular case you should implement two-way binding. It'll work like this:

class Keyboard extends React.Component {
  state = {
    current: null,
    keys: ["á", "é", "í", "ñ", "ó", "ú", "ü"]
  };

  render() {
    return (
      <div>
        <table>
          <tbody>
            {Object(
              this.state.keys.map(key => {
                return (
                  <td>
                    <button
                      onClick={() => {
                        this.solve(key, this.props.handler);
                      }}
                    >
                      {key}
                    </button>
                  </td>
                );
              })
            )}
          </tbody>
        </table>
      </div>
    );
  }
  solve = (char, callback) => {
    this.setState({ current: char });
    callback(char);
    return;
  };
}

class TextBox extends React.Component {
  render() {
    return (
      <div>
        <form onSubmit={this.mySubmitHandler}>
          <input
            value={this.props.equation}
            size="35"
            type="text"
            name="equation"
            onChange={this.handleInputChange}
          />
        </form>
      </div>
    );
  }
  handleInputChange = event => {
    event.preventDefault();
    this.setState({
      [event.target.name]: event.target.value
    });
    this.props.equationChange(event.target.value)
  };

  mySubmitHandler = event => {
    event.preventDefault();
    alert("You are submitting " + this.props.equation);
    console.log(this.props.equation);
  };
}

class App extends React.Component {
  state = { character: null };
  render() {
    return (
      <div>
        <TextBox equationChange={this.equationChange} equation={this.state.equation} />
        <Keyboard handler={this.handler} />
      </div>
    );
  }

  handler = arg => {
    console.log(arg);
    this.setState({ equation: (this.state.equation || '') + arg
                  });
  };

  equationChange = equation => {
    this.setState({ equation });
  }
}

React.render(<App />, document.getElementById('app'));

A working codepen: https://codepen.io/leo-melin/pen/mdyEvwQ

Sign up to request clarification or add additional context in comments.

Comments

1

This can be achieved by passing the state variable character this.state.character to the child component Textbox in App.js, and this.handler method in App.js should update the this.state.character.

class App extends Component {
  state = { character: null };
  render() {
    return (
      <div>
        <TextBox character={this.state.character} />
        <Keyboard handler={this.handler} />
      </div>
    );
  }

  handler = arg => this.setState({ character: arg });
}

Comments

0

You can pass this.state.character as prop to textbox and then in textbox.jsx extract character from props i.e const {character} = this.props and then display it in textbox.

Comments

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.