This issue is part of the larger effort to modernize the Jaeger UI codebase (Parent Issue #2610). The goal is to refactor the DependencyGraph component from a React Class Component to a React Functional Component using Hooks.
Target Component: packages/jaeger-ui/src/components/DependencyGraph/index.tsx
Acceptance Criteria
Migration Guide (Cheat Sheet)
| Feature |
Old (Class) |
New (Functional) |
| State |
this.state = { isOpen: false } |
const [isOpen, setIsOpen] = useState(false); |
| Side Effects |
componentDidMount() |
useEffect(() => { ... }, []) |
| Props |
this.props.traceId |
props.traceId (or destructure: const { traceId } = props;) |
| Default Props |
static defaultProps = { name: 'Guest' } |
function Component({ name = 'Guest' }) { ... } |
| Performance |
class MyComp extends React.PureComponent |
export default React.memo(MyComp) |
| Context |
static contextType = MyContext |
const val = useContext(MyContext) |
| Refs |
this.myRef = React.createRef() |
const myRef = useRef(null) |
Common Pitfalls (Read Carefully!)
- Stale Closures: Be careful when using
useEffect. If you use a variable inside the effect that comes from props or state, it must be in the dependency array. If you omit it, the effect will use the old value.
- Testing with Enzyme: Functional components do not have instances. Tests like
wrapper.instance().method() or wrapper.state('value') will fail. You should refactor these tests to simulate events (clicks) and check the rendered output instead.
Resources
This issue is part of the larger effort to modernize the Jaeger UI codebase (Parent Issue #2610). The goal is to refactor the
DependencyGraphcomponent from a React Class Component to a React Functional Component using Hooks.Target Component:
packages/jaeger-ui/src/components/DependencyGraph/index.tsxAcceptance Criteria
this.stateis replaced withuseStateoruseReducer.useEffect.connectHOC is replaced withuseSelectoranduseDispatchhooks (optional but preferred).PureComponent, the new one is wrapped inReact.memo.state()orinstance(), they must be refactored to check the DOM or Props instead.Migration Guide (Cheat Sheet)
this.state = { isOpen: false }const [isOpen, setIsOpen] = useState(false);componentDidMount()useEffect(() => { ... }, [])this.props.traceIdprops.traceId(or destructure:const { traceId } = props;)static defaultProps = { name: 'Guest' }function Component({ name = 'Guest' }) { ... }class MyComp extends React.PureComponentexport default React.memo(MyComp)static contextType = MyContextconst val = useContext(MyContext)this.myRef = React.createRef()const myRef = useRef(null)Common Pitfalls (Read Carefully!)
useEffect. If you use a variable inside the effect that comes from props or state, it must be in the dependency array. If you omit it, the effect will use the old value.wrapper.instance().method()orwrapper.state('value')will fail. You should refactor these tests to simulate events (clicks) and check the rendered output instead.Resources
connect().