Do you "have to" build a NodeView as a React component?

Just out of curiosity. I read many posts here asking how to render a nodeview as a react component. i am curious why do you have to do that. if the sole reason is to share the state with react, you can just sync the editor view with react state and check if the props change (and then do whatever is necessary). or is it because react devs get freaked out when anything is directly manipulating the DOM?

You really don’t. It can provide some convenient sharing of primitives that you might want to use when building more complicated non-editable stuff, but in most cases it’s much less complicated and more performant to just use plain DOM.

1 Like

Thank you for sharing your opinion. If you don’t mind, could you please provide more information about the sharing of primitives?

Say you have a react-based button all over your app, and you want to use the same behavior and style in a button inside a node view, it’ll be convenient to use the React component there.

1 Like

Aha i see! Thank you very much. I love your work by the way!

1 Like

As one of the people sharing ways to implement Node Views React components… I fully agree with Marijn! One of the top contenders in our recent rebuild of our ProseMirror/React integration was “just stop using React for Node Views”, and it was genuinely quite appealing! In the end we decided to keep using React components for Node Views largely because we use those same components to actually render stories on nytimes.com, and sharing the components themselves means that our journalists are much more likely to see a relatively accurate representation in our editor of what their stories will look like once published. If you don’t already have a system that is built with (and heavily dependent on) React that you need to be able to share code with, I wouldn’t personally recommend looking to React for building ProseMirror-related UI

3 Likes

We were using React to render node-views and replaced it with calls to the crel library (wraps document.createElement) and found it greatly simplified our codebase and eliminated a fair number of bugs along the way. We didn’t have the benefit the nyt folks had of sharing views between the editor and the front end to lose though.

we use those same components to actually render stories

Hi, is it possible to share some code examples of how you’re reusing react components between react node views and normal react?

E.g. what are some non-trivial components already implemented in react, that would be hard to port into a vanilla node view.

Curious since I would think react does well with non contenteditable content, so what would you put into your editor that writers want to see but can’t edit (?).

We should add some examples to GitHub - nytimes/react-prosemirror: A fully featured library for safely integrating ProseMirror and React.! I can’t share any code samples at the moment, but to take a random story from today’s front page: https://www.nytimes.com/2023/04/02/nyregion/bruce-springsteen-garden-trump.html

All of the blocks in that story are implemented in React, and most of those React components are directly used (sometimes with wrappers to add additional interactivity) in our text editor. So, for example, the “Sign up for the New York Today Newsletter” box is (or could be, at least, I can’t remember exactly if we actually did this literal block this way) represented as a ProseMirror block with two inline child nodes, both of which are directly editable. Even the “Michael Wilson is a reporter on the Metro desk…” detail block at the end is a React component; in the text editor, we wrap it with another component that provides a Twitter-style @-mention feature, so that journalists don’t have to worry as much about accidentally messing up each other’s names.

There are more complex blocks that get better mileage out of being implemented in React, I was just having trouble finding any stories that use them to link as examples right now. But in general, it’s valuable to just share all of the block components, so that there’s as little special-casing as possible (and so that if we change how something appears on the website, it more-or-less automatically changes how it appears in the text editor, as well)

2 Likes

Hello @SMores I’m working on something similar and wanted to clarify - do you mean you have managed to reuse React components in the editor and in the actual frontend for nytimes? That sounds like exactly what I’m trying to achieve but I’m struggling to see how I can easily reuse a previously built React component in the editor without having to reimplement it so that the text fields are actually editable.

Would it be possible to give me some pointers on what I’m missing regarding how I can achieve that with the nytimes/react-prosemirror library? Or if you could share any simple made up examples of this pattern? Thank you very much!

I do! But it required some careful effort; it didn’t just come for free by using this library, unfortunately. I also haven’t worked at the Times in about a year, so my memory isn’t perfect on this, but:

Components would have to be designed to accept data in both forms; as ProseMirror nodes, and as the nodes in the NYT GraphQL schema. For more complex components, this often looked like having thin wrappers, one for the frontend, which took the GraphQL data and then composed its children as needed, and one for ProseMirror, where ProseMirror would instead be responsible for composing children. So underlying structural components would be shared, but there was often still context-aware code that had to know whether it was in the frontend or the editor.

Yeah, this I don’t think will really be possible, unfortunately :frowning:. You can certainly reuse parts of your components, or create ProseMirror-specific wrappers that render your existing components (this will be especially more straightforward if you check out the next tag, code and docs here), but won’t be able to use existing components entirely without modification.

1 Like