React Flow如何通过style prop实现节点选中、聚焦状态样式设置
核心结论
你使用的&:focus属于CSS-in-JS的伪类语法,React Flow的节点style属性仅支持标准CSS内联样式对象,原生内联样式本身不支持伪类选择器,因此该写法无法生效,也不能直接通过style prop设置选中、聚焦状态样式。
可用解决方案
方案1:覆盖React Flow内置类名(最简便)
React Flow会自动给选中的节点添加react-flow__node-selected类,给聚焦的节点添加react-flow__node-focused类,直接编写CSS规则覆盖样式即可,无需修改JS逻辑:
/* 节点默认样式 */ .react-flow__node { padding: 0.7rem; height: 7rem; width: 12rem; border-color: #868DA0; border-radius: 3px; } /* 选中/聚焦样式 */ .react-flow__node-selected, .react-flow__node:focus { background-color: blue; color: blue; padding: 5rem; border-radius: 7px; }
方案2:监听选中事件动态切换style
如果不想写全局CSS,可以通过React Flow提供的onSelectionChange事件监听选中状态,动态给节点匹配对应样式,无需单独维护每个节点的状态:
import { useState, useCallback } from 'react'; import ReactFlow, { SelectionChangeEvent } from 'reactflow'; // 定义默认样式和选中样式 const defaultNodeStyle = { padding: '0.7rem', height: '7rem', width: '12rem', borderColor: '#868DA0', borderRadius: '3px', }; const selectedNodeStyle = { ...defaultNodeStyle, backgroundColor: 'blue', color: 'blue', padding: '5rem', borderRadius: '7px', }; export default function Flow({ items, itemConnections }: FlowProps) { // 存储当前选中的节点ID集合 const [selectedNodeIds, setSelectedNodeIds] = useState<Set<string>>(new Set()); const handleSelectionChange = useCallback((event: SelectionChangeEvent) => { const selectedIds = new Set(event.nodes.map(node => node.id)); setSelectedNodeIds(selectedIds); }, []); const nodes = items.map(({ id, x_position, y_position, name }) => ({ id, data: { label: name }, position: { x: x_position, y: y_position }, // 动态匹配样式 style: selectedNodeIds.has(id) ? selectedNodeStyle : defaultNodeStyle, })) return ( <Box> {items.length === 0 ? ( <EmptyFlowBox /> ) : ( <ReactFlow elements={[...nodes, ...itemConnections]} onSelectionChange={handleSelectionChange} > <Controls /> </ReactFlow> )} </Box> ) }
方案3:使用自定义节点(灵活度最高)
如果是自定义节点组件,React Flow会给组件传入selected、focused两个状态prop,直接根据这两个prop设置内联样式即可:
// 自定义节点组件 const CustomNode = ({ data, selected, focused }) => { return ( <div style={{ padding: '0.7rem', height: '7rem', width: '12rem', borderColor: '#868DA0', borderRadius: '3px', ...(selected || focused ? { backgroundColor: 'blue', color: 'blue', padding: '5rem', borderRadius: '7px', } : {}) }}> {data.label} </div> ) } // 注册自定义节点 const nodeTypes = { custom: CustomNode } // 生成节点时指定type为custom const nodes = items.map(({ id, x_position, y_position, name }) => ({ id, type: 'custom', data: { label: name }, position: { x: x_position, y: y_position } })) // 渲染时传入nodeTypes <ReactFlow nodeTypes={nodeTypes} elements={[...nodes, ...itemConnections]} />
内容的提问来源于stack exchange,提问作者Haq.H
相关产品推荐
相关产品推荐

