Skip to main content

ReactJS Double Click to Edit Text

This article will use a simple React project to show you how to click (or double-click) to edit a page's text.

Here is a demo of the full name bio app we will build:

http://localhost:3000

Double click to edit text animation

Notice that I've intentionally made the final outcome as simple as possible to avoid confusing you with unnecessary elements.

Without any further ado, let's get started with the first step.

Step 1: Get the Right Node and NPM Version

Ensure that you have Node 10.16 (or greater) and NPM 5.6 (or greater) installed on your system.

note

Step 2: Create a New React App

Use NPM's create-react-app package to create a new React app called click-text-to-edit-project.

npx create-react-app click-text-to-edit-project

Alternatively, you can use Yarn to configure your project like so:

yarn create react-app click-text-to-edit-project

Step 3: Go Inside the Project Directory

After the installation process, navigate into the project directory like so:

cd click-text-to-edit-project

Step 4: Clean Up the src Folder

Delete all files inside the project directory's src folder.

Step 5: Create your code files

Create the following files inside your project's src folder.

  • index.js
  • App.js
  • ElementMaker.js

Step 6: Render the App component

Open your index.js file and render the App component to the DOM like so:

// index.js

import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

// Render the App component into the root DOM
createRoot(document.getElementById("root")).render(<App />);

Step 7: Create the ElementMaker Component

Here is where the wonders happen!

Open your ElementMaker.js file and replicate the code below. We will go through its explanation afterward.

// ElementMaker.js

import React from "react";
import { Component } from "react";

// Creat an ElementMaker component
class ElementMaker extends Component {
// Render a <span> element
render() {
return (
<span>
{
// Use JavaScript's ternary operator to specify <span>'s inner content
this.props.showInputEle ? (
<input
type="text"
value={this.props.value}
onChange={this.props.handleChange}
onBlur={this.props.handleBlur}
autoFocus
/>
) : (
<span
onDoubleClick={this.props.handleDoubleClick}
style={{
display: "inline-block",
height: "25px",
minWidth: "300px",
}}
>
{this.props.value}
</span>
)
}
</span>
);
}
}

export default ElementMaker;

In the snippet above, we did the following:

  1. We created an ElementMaker component that uses React's render() lifecycle method to render a <span> element.
  2. We used the ternary operator to specify the <span>'s inner content.

Simply put, the ternary operator says that if this.props.showInputEle's value is truthy, the computer should use the given <input> element as the <span>'s inner content.

However, if this.props.showInputEle's value is falsy, the computer should use a second <span> element as the first <span>'s inner content.

And here is the function component alternative of the ElementMaker:

// ElementMaker.js

import React from "react";

// Create an ElementMaker component
function ElementMaker(props) {
return (
<span>
{
// Use JavaScript's ternary operator to specify <span>'s inner content
props.showInputEle ? (
<input
type="text"
value={props.value}
onChange={props.handleChange}
onBlur={props.handleBlur}
autoFocus
/>
) : (
<span
onDoubleClick={props.handleDoubleClick}
style={{
display: "inline-block",
height: "25px",
minWidth: "300px",
}}
>
{props.value}
</span>
)
}
</span>
);
}

export default ElementMaker;

Keep in mind that we've not defined showInputEle—we will do that soon.

For now, though, you may have observed that we specified five attributes on the <input> element: type, value, onChange, onBlur, and autoFocus.

Here is the purpose of each attribute:

  • The type="text" attribute specifies that the <input> element is a single-line text field.
  • We used the value attribute to set the <input> element's content to the props parameter's value property.
  • onChange is an event listener that will trigger the handleChange function whenever <input>'s value changes. Note that we will later define handleChange in our App component.
  • onBlur is an event listener that will trigger the handleBlur function whenever <input> loses focus. In other words, onBlur will invoke handleBlur whenever users click out of the <input> field. Note that we will later define handleBlur in our App component.
  • autoFocus is a Boolean attribute that tells the browser to focus automatically on the <input> element when the page loads.

We also specified an onDoubleClick event listener on the second <span> element.

The onDoubleClick listener will trigger the handleDoubleClick function whenever users double-click the <span> element.

Keep in mind that we will later define handleDoubleClick in our App component.

note

Suppose you wish to make the text editable with a single click. In that case, simply change the onDoubleClick event listener to onClick.

Step 8: Invoke the ElementMaker Component

Remember that we aim to display a full name bio that users can double-click to edit.

So, open your App.js file and replicate the code below. We will go through its explanation afterward.

// App.js

import React from "react";
import { Component } from "react";
import ElementMaker from "./ElementMaker";

// Create an App component
class App extends Component {
constructor() {
super();

// Set App's state
this.state = {
fullName: { text: "Joe Abraham", showInputEle: false },
};
}

render() {
return (
<div>
<h1>Double-click the Full Name's Value to Edit</h1>
<div>
<strong>Full Name: </strong>
{/* Invoke the ElementMaker component with some attributes */}
<ElementMaker
value={this.state.fullName.text}
handleChange={(e) =>
this.setState({
fullName: {
text: e.target.value,
showInputEle: this.state.fullName.showInputEle,
},
})
}
handleDoubleClick={() =>
this.setState({
fullName: { ...this.state.fullName, showInputEle: true },
})
}
handleBlur={() =>
this.setState({
fullName: { ...this.state.fullName, showInputEle: false },
})
}
showInputEle={this.state.fullName.showInputEle}
/>
</div>
</div>
);
}
}

export default App;

In the snippet above, we did the following:

  1. We imported our ElementMaker component from the ElementMaker.js file.
  2. We created an App component and set its state to a fullName object that contains a text property and a showInputEle property.
    • The text property stores each content the user types into ElementMaker's <input> element. Note that we used "Joe Abraham" as text's default value.
    • The showInputEle property stores the Boolean value true or false. Remember that we used the showInputEle property in ElementMaker to determine the <span>'s inner content.
  3. In App's render() method, we used the <ElementMaker /> code to invoke the ElementMaker component. Then we passed some attributes to ElementMaker's props parameter. The attributes we passed in are value, handleChange, handleDoubleClick, handleBlur, and showInputEle.
    • The value attribute keeps App's fullName text state.
    • handleChange's function updates the state's fullName property with the ElementMaker's input element's value.
    • handleDoubleClick's function updates the state's showInputEle property with the Boolean value true.
    • handleBlur's function updates the state's showInputEle property with the Boolean value false.
    • We initialized showInputEle with the state's showInputEle property.

Here is the function component equivalence of the App component:

// App.js

import React, { useState } from "react";
import ElementMaker from "./ElementMaker";

// Create an App component
function App() {
// Set App's state
const [fullName, setFullName] = useState("Joe Abraham");
const [showInputEle, setShowInputEle] = useState(false);

return (
<div>
<h1>Double-click the Full Name's Value to Edit</h1>
<div>
<strong>Full Name: </strong>
{/* Invoke the ElementMaker component with some attributes */}
<ElementMaker
value={fullName}
handleChange={(e) => setFullName(e.target.value)}
handleDoubleClick={() => setShowInputEle(true)}
handleBlur={() => setShowInputEle(false)}
showInputEle={showInputEle}
/>
</div>
</div>
);
}

export default App;

Step 9: Making Sense of It All

So, now that we've done the coding aspect, let's discuss how the browser will implement it all.

  1. The browser will read App.js and render its <h1> and <strong> elements.
  2. On getting to the <ElementMaker /> code, the browser will invoke the ElementMaker component and pass in the specified attributes to its props parameter.
  3. ElementMaker will return its <span> element. But the <span>'s inner content will depend on props.showInputEle's value.
    • If showInputEle's value is truthy, the <input> element will be the <span>'s inner content.
    • If showInputEle is falsy, the second <span> element will get rendered as the <span>'s inner content.
  4. Suppose showInputEle is falsy, and the second <span> element with the text "Joe Abraham" gets rendered in the browser. In that case, the <span>'s onDoubleClick event listener will trigger the handleDoubleClick function when you double-click the text. Then, handleDoubleClick's invocation will update the state's showInputEle property to true.
  5. As a result of the state update, React will automatically re-invoke App's render() method. Consequently, render() will trigger ElementMaker—which will check if showInputEle is truthy.
  6. Since showInputEle is now truthy, the <input> element will get set as the <span>'s inner content.
  7. Each time the user types into the text field, <input> element's onChange listener will trigger handleChange. Then, handleChange will update the state's fullName property with the user's data.
  8. Once the user clicks out of the <input> field, onBlur will trigger handleBlur—which will update showInputEle to false.
  9. As a result of the state update, React will re-invoke App's render() method.
  10. render() will trigger ElementMaker—which will check if showInputEle is truthy.
  11. Since showInputEle is now falsy, the <span> with the onDoubleClick attribute will get set as the first <span>'s inner content.

And there you have it! You've now seen how to click to edit elements in ReactJS!

Step 10: Run the Application

Take a look at your app in the browser by running:

npm start

Or, if your package manager is Yarn, run:

yarn start

You can also see my class component version here. Or check here if you prefer function components.

Wrapping It Up

Although this article used a simple React project to illustrate how you can double-click to edit a web page's text, the principles covered applies to any React application.

So, you can use the concepts you've learned to add validations or make images (or an entire webpage) editable on double-click.

If you like this article, please Tweet it.

Thanks for reading!