React+Material UI:能否在输入框中渲染React组件?
Hey there! I totally get what you're trying to build—mixing plain text with interactive Material UI Chips for variables in an input experience. Native <input> or <textarea> elements won't work here because they only handle plain text, so let's break down your best options.
Option 1: Build a Custom contenteditable Container
Since native inputs can't render React components, the most straightforward approach (for simpler use cases) is to use a contenteditable div (wrapped in a Material UI component like Box). Here's how to make this work:
- Listen to input events to capture the current text content.
- Parse text with regex to split it into plain text segments and variable matches (like
$name). - Render mixed content: Map over parsed segments, rendering plain text for regular parts and Material UI Chips for variables.
- Handle cursor management (the tricky part—you'll need to adjust cursor position after inserting a Chip to keep editing smooth).
Here's a minimal example to kick things off:
import { useState } from 'react'; import { Chip, Box } from '@mui/material'; const VariableInput = () => { const [rawContent, setRawContent] = useState('Hello, my name is $name and I work at $company'); // Split content into text and variable parts const parseContent = (text) => { // Regex to match variables starting with $ followed by letters/numbers const regex = /(\$\w+)/g; const segments = text.split(regex); return segments.map((segment, index) => { if (segment.startsWith('$')) { const variableLabel = segment.slice(1); return ( <Chip key={index} label={variableLabel} variant="outlined" sx={{ margin: '0 4px' }} /> ); } return segment; }); }; const handleInput = (e) => { setRawContent(e.currentTarget.textContent); }; return ( <Box contentEditable onInput={handleInput} sx={{ border: '1px solid #e0e0e0', borderRadius: 1, padding: '8px', minHeight: '40px', outline: 'none', '&:focus': { borderColor: '#2196f3', }, }} > {parseContent(rawContent)} </Box> ); }; export default VariableInput;
Option 2: Use a Rich Text Editor Library
If your use case gets more complex (like reliable cursor positioning, copy-paste support, or advanced formatting), you’ll save yourself headaches by using a mature rich text editor that supports custom React components. Top choices include:
- Slate.js: A highly customizable framework for building rich text editors. You can define custom inline nodes that render as Material UI Chips, and set up logic to auto-convert
$variabletext into these Chip nodes. - Draft.js: Facebook’s rich text editor framework. It supports custom decorators that match your variable regex and render Chips in place of raw text.
These libraries handle low-level details like cursor management and content state out of the box—way easier than building all that from scratch.
Why material-ui-chip-input Isn't the Right Fit
You mentioned material-ui-chip-input didn’t meet your needs, and that makes sense! That library is designed for scenarios where users add/remove Chips as discrete inputs (like a tag selector), not for mixing Chips directly within flowing text.
Final Thoughts
- For simple use cases: Go with the
contenteditableapproach, but be prepared to handle edge cases like cursor positioning. - For production-grade, complex needs: Invest time in learning Slate or Draft.js—they’ll give you the flexibility you need without reinventing the wheel.
Hope this helps you move forward with your project!
内容的提问来源于stack exchange,提问作者Paikz

