Acitivity.
js
import React, { useState, useEffect, useContext, useRef, useReducer, useCallback,
useMemo } from 'react';
// Context for managing global state
const TextContext = React.createContext();
const initialState = {
texts: [],
};
// Reducer function for managing text state
function textReducer(state, action) {
switch (action.type) {
case 'ADD_TEXT':
return { texts: [...state.texts, action.payload] };
case 'REMOVE_TEXT':
return { texts: state.texts.filter((_, index) => index !== action.payload) };
default:
return state;
}
}
const TextProvider = ({ children }) => {
const [state, dispatch] = useReducer(textReducer, initialState);
return (
<TextContext.Provider value={{ state, dispatch }}>
{children}
</TextContext.Provider>
);
};
const TextHooks = () => {
const { state, dispatch } = useContext(TextContext);
const [inputText, setInputText] = useState('');
const inputRef = useRef(null);
// Effect to focus on input field when component mounts
useEffect(() => {
inputRef.current.focus();
}, []);
// Memoized value for character count
const totalCharacters = useMemo(() => {
return state.texts.join('').length;
}, [state.texts]);
// Callback to handle adding text
const handleAddText = useCallback(() => {
if (inputText.trim()) {
dispatch({ type: 'ADD_TEXT', payload: inputText });
setInputText('');
}
}, [inputText, dispatch]);
// Callback to handle removing text
const handleRemoveText = (index) => {
dispatch({ type: 'REMOVE_TEXT', payload: index });
};
return (
<div>
<h1>Text Hooks App</h1>
<input
ref={inputRef}
type="text"
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="Enter text"
/>
<button onClick={handleAddText}>Add Text</button>
<h2>Total Characters: {totalCharacters}</h2>
<ul>
{state.texts.map((text, index) => (
<li key={index}>
{text} <button onClick={() => handleRemoveText(index)}>Remove</button>
</li>
))}
</ul>
</div>
);
};
const Activity = () => (
<TextProvider>
<TextHooks />
</TextProvider>
);
export default Activity;