I am trying to make a text editor in react.Does anyone knows how to get the selected text from the textarea so that styles can be applied on the selected text.I know we can use window.getSelection in javascript but I am curious to know If any other methods are available for this functionality?
3 Answers
Yes there is a method to do this, specially in React. The way you should go to achieve this is as follow.
step 1:- use ref in your textarea ui element. like
`<textarea
className='html-editor'
ref='myTextarea'
value = {this.state.textareaVal}
onChange={(event)=>{
this.setState({
textareaVal:event.target.value;
});
}}
>
</textarea>`
step 2:- now you can access the DOM element,using react refs.
let textVal = this.refs.myTextarea;
step 3:- use selectionStart and selectionEnd :- using selectionStart and
selectionEnd you can get to know your start and end pointer
of selected text.which can be done as below;
let cursorStart = textVal.selectionStart;
let cursorEnd = textVal.selectionEnd;
now you have start and end index of your selected text.
step 4 :- use javascript substring function to get the selected text.
this.state.textareaVal.substring(cursorStart,cursorEnd)

- 136
- 4
The best way to make a Text Editor in React is to use DraftJS.
If you are using React, DraftJS is the way to go about it. It abstracts away many of the challenges you would face while trying to create your own text editor from scratch. This includes managing the state of your editor (similarly to how you would manage a component's state), managing text selection, applying different attributes and so on.
You can get started by checking out the docs, and I would suggest watching the introduction video on that page, which goes through the difficulties DraftJS aims to solve.
I hope that helps.

- 115
- 1
- 12
-
1DraftJS almost provides *too* much functionality, and comes in at around 60 kb gzipped which is a big library. For comparison have created my own text editor in preact (with rich styling and images) for only 9 kb gzipped *without DraftJS*. But for React a library like DraftJS or Slate is better to use because React does not diff with the DOM, but instead the VDOM, so you have to keep the two in sync, whereas with preact you don't (because preact is forgiving). – notrota Apr 01 '18 at 06:47
-
DraftJS is pretty much abandonware right now. The guys at Facebook are trying to maintain it on their own, but it's veeeeeery slow and there are numerous issues with it (starting with the fact that it has a linear value structure, not a tree to mirror the actual DOM). – Almaron Jan 01 '19 at 14:45
-
Do you have an alternative recommendation @Almaron? It does look like the rate of contributions isn't very fast, but it still seems better than any alternative I have found – Zach Smith Jan 18 '19 at 10:01
-
I have settled on using SlateJS. Best thing for me - it's a tree-structrure like it should be, and it's pretty easy to setup and use. One downside is - does not support IE/Edge and has some minor glitches on mobile platforms. But I can live with that for now. – Almaron Jan 19 '19 at 09:15
How to do it in functional component? Expanding on the answer given by Sanjeev.
function MyEditor() {
const [state,setValue] = useState({value: ""});
//1
const myRef = React.createRef()
const inputsHandler = (e) =>{
var taxt = e.target.innerHTML
let textArray = taxt.split(/\n/gm)
console.log(textArray)
setValue( {value: e.target.value} )
}
const onDone = () => {
console.log("on done", stateNew)
dispatch(updateEditorVisibility())
// dispatch(props.reducer(state.value))
dispatch(stateNew.editorReducerAction(state.value))
}
return (
<div>
<textarea
type="text"
ref={myRef}
name="first_name"
onChange={inputsHandler}
value={state.value}/>
<button onClick={() => {
let textVal = myRef.current;
let cursorStart = textVal.selectionStart;
let cursorEnd = textVal.selectionEnd;
let selectedText = state.value.substring(cursorStart,cursorEnd)
console.log(selectedText)
}}>Log</button>
</div>
)}
Create a ref using create ref
const myRef = React.createRef();
set the ref in your textarea
ref={myRef}
To access use
let cursorStart = textVal.selectionStart; let cursorEnd = textVal.selectionEnd; let selectedText = state.value.substring(cursorStart,cursorEnd) console.log(selectedText)````

- 11
- 2