#reactjs #react-redux
Вопрос:
У меня есть этот пример кода на моем контейнере
import TopicDetail, {
Props,
} from '../TopicDetail';
type ContainerProps = Partial<Props>;
function Topic(
props: ContainerProps,
): React.ReactElement<Props> {
const dispatch = useDispatch();
const topics = useSelector(getTopicReview);
React.useEffect(() => {
dispatch(fetchTopicReviewRequest());
}, []);
// topics = { [topic1],[topic2] }
return (
<TopicDetail
{...props}
topicReview={topics}
/>
);
}
export default Topic;
В то время как реквизиты Темы будут расположены на странице темы, и это не проблема.
Вопрос в том, когда я хочу вызвать эту тему в другом компоненте под названием TopicHead, я хочу получить значение тем, расположенных внутри компонента Темы, и я пытаюсь использовать подход, как показано ниже, но это не сработало, и темы просто возвращают undefined
значение
// In Another Component
import Topic, {
Props,
} from '../Topic';
function TopicHead(){
var topics;
<Topic {..props} topics{topics} />
// topics = { [topic1],[topic2] }
};
Есть ли какой-либо возможный способ получить его значение в топике?
Ответ №1:
Один из способов-передать реквизиты с помощью useState
крючка, а затем убедиться, что при каждом topics
изменении в Topic
компоненте setState
вызывается метод для родителя.
import TopicDetail, { Props } from '../TopicDetail';
type ContainerProps = Partial<Props> amp; {
onChange: (value: any) => void
};
function Topic(
props: ContainerProps,
): React.ReactElement<Props> {
const dispatch = useDispatch();
const topics = useSelector(getTopicReview);
React.useEffect(() => {
dispatch(fetchTopicReviewRequest());
}, []);
// topics = { [topic1],[topic2] }
React.useEffect(() => props.onChange(topics), [topics])
return (
<TopicDetail
{...props}
topicReview={topics}
/>
);
}
export default Topic;
А затем компонент TopicHead.
// In Another Component
import Topic, { Props } from '../Topic';
function TopicHead(){
const [topics, setTopics] = useState();
<Topic {..props} onChange={setTopics} />
// topics = { [topic1],[topic2] }
};
Конечно, мне не удалось это проверить, но я надеюсь, что вы поймете, в чем дело, даже если это не совсем работает. Кроме того, убедитесь, что вы обращаетесь topics
TopicHead
с ним осторожно, иначе это может привести к чрезмерной повторной визуализации.
Комментарии:
1. Я понимаю вашу точку зрения, спасибо. Я сообщу вам об этом, как только попробую этот подход
Ответ №2:
Я предполагаю useDispatch
, что и useSelector
от react-redux
, и поэтому вы используете redux для хранения тем.
Таким образом, вы можете использовать один и тот же селектор в своем TopicHead
.
function TopicHead(){
const topics = useSelector(getTopicReview);
<Topic {..props} topics={topics} />
// topics = { [topic1],[topic2] }
};
Редактировать
Я знаю, что это возможно, но в моем случае по теме существует довольно много логики для получения окончательного значения темы.
Обычно я переношу всю логику в редукторы, потому что их легче проверить. Таким образом, у меня обычно не возникает проблемы с доступом к логике в другом компоненте.
В любом случае, вы можете передать Topic
компоненту задатчик состояния. Так что Topic
можно вызвать этот метод, если его логика вычислила новое значение для темы. Например.
function TopicHead(){
const [topic, setTopic] = useState();
<Topic {..props} onTopicChanged={setTopic} />
};
Кроме того, если я добавлю элемент выбора использования в заголовке темы, вызов redux будет вдвое больше, не так ли?
Да, но это просто выбор значения из состояния , например state.topics[0].name
, не так ли? Вас беспокоят проблемы с производительностью? Выбор значения из состояния обычно не занимает много времени, поскольку все значения уже вычислены редукторами. Я сказал «обычно», потому что вы можете нарушить этот шаблон и выполнять трудоемкие действия в селекторе, но я надеюсь, что вы этого не сделаете.
Комментарии:
1. Я знаю, что это возможно, но в моем случае по теме существует довольно много логики для получения окончательного значения темы. Поэтому я думаю, что можно просто проанализировать конечное значение из темы в заголовок темы. А также, если я добавлю
useSelector
в заголовке темы, будет двойной вызов redux, не так ли? так как я не могу удалитьuseSelector
вызов в теме