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:
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
Make sure you have Node 10.16 (or greater) and NPM 5.6 (or greater) installed on your system.
- Use this guide to install, update, or verify your Node version.
- If you prefer to use Yarn, make sure you have Yarn 0.25 (or greater).
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:
- We created an
ElementMaker
component that uses React'srender()
lifecycle method to render a<span>
element. - 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 theprops
parameter'svalue
property. onChange
is an event listener that will trigger thehandleChange
function whenever<input>
's value changes. Note that we will later definehandleChange
in ourApp
component.onBlur
is an event listener that will trigger thehandleBlur
function whenever<input>
loses focus. In other words,onBlur
will invokehandleBlur
whenever users click out of the<input>
field. Note that we will later definehandleBlur
in ourApp
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.
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:
- We imported our
ElementMaker
component from theElementMaker.js
file. - We created an
App
component and set itsstate
to afullName
object that contains atext
property and ashowInputEle
property.- The
text
property stores each content the user types intoElementMaker
's<input>
element. Note that we used"Joe Abraham"
astext
's default value. - The
showInputEle
property stores the Boolean valuetrue
orfalse
. Remember that we used theshowInputEle
property inElementMaker
to determine the<span>
's inner content.
- The
- In
App
'srender()
method, we used the<ElementMaker />
code to invoke theElementMaker
component. Then we passed some attributes toElementMaker
'sprops
parameter. The attributes we passed in arevalue
,handleChange
,handleDoubleClick
,handleBlur
, andshowInputEle
.- The
value
attribute keepsApp
'sfullName
text
state. handleChange
's function updates the state'sfullName
property with theElementMaker
's input element's value.handleDoubleClick
's function updates the state'sshowInputEle
property with the Boolean valuetrue
.handleBlur
's function updates the state'sshowInputEle
property with the Boolean valuefalse
.- We initialized
showInputEle
with the state'sshowInputEle
property.
- The
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.
- The browser will read
App.js
and render its<h1>
and<strong>
elements. - On getting to the
<ElementMaker />
code, the browser will invoke theElementMaker
component and pass in the specified attributes to itsprops
parameter. ElementMaker
will return its<span>
element. But the<span>
's inner content will depend onprops.showInputEle
's value.- Suppose
showInputEle
is falsy, and the second<span>
element with the text"Joe Abraham"
gets rendered in the browser. In that case, the<span>
'sonDoubleClick
event listener will trigger thehandleDoubleClick
function when you double-click the text. Then,handleDoubleClick
's invocation will update the state'sshowInputEle
property totrue
. - As a result of the state update, React will automatically re-invoke
App
'srender()
method. Consequently,render()
will triggerElementMaker
—which will check ifshowInputEle
is truthy. - Since
showInputEle
is now truthy, the<input>
element will get set as the<span>
's inner content. - Each time the user types into the text field,
<input>
element'sonChange
listener will triggerhandleChange
. Then,handleChange
will update the state'sfullName
property with the user's data. - Once the user clicks out of the
<input>
field,onBlur
will triggerhandleBlur
—which will updateshowInputEle
tofalse
. - As a result of the state update, React will re-invoke
App
'srender()
method. render()
will triggerElementMaker
—which will check ifshowInputEle
is truthy.- Since
showInputEle
is now falsy, the<span>
with theonDoubleClick
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 live version on Stackblitz:
Overview
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.