#reactjs #react-hooks #use-state
#reactjs #реагирующие хуки #use-state
Вопрос:
У меня есть для категорий с полями изображения и описания. каждое описание содержит большой текст, если он превышает 200 слов, тогда должна отображаться read more
ссылка. При нажатии на подробнее там также должен отображаться полный текст со readless
ссылкой. Я попробовал приведенный ниже код, но если я нажму на 1-ю подкатегорию, откроется enter code here
ссылка на все категории для чтения. если я нажму readless, это сработает для всех других категорий readless link. Как сделать каждую работу отдельной с помощью ссылок readmore и readless.
Вот мой код
У меня есть для категорий с полями изображения и описания. каждое описание содержит большой текст, если он превышает 200 слов, тогда должна отображаться read more
ссылка. При нажатии на подробнее там также должен отображаться полный текст со readless
ссылкой. Я попробовал приведенный ниже код, но если я нажму на 1-ю подкатегорию, откроется enter code here
ссылка на все категории для чтения. если я нажму readless, это сработает для всех других категорий readless link. Как сделать каждую работу отдельной с помощью ссылок readmore и readless.
Вот мой код
import React,{useState} from 'react';
export function FullReport(props) {
const [readMore, setReadMore] = React.useState(false);
const linkName = readMore ? "...Read Less" : "...Read More";
const [categories, setcategories] = React.useState([]);
React.useEffect(() => {
try {
axios
.get(
`/getReportDetails`
)
.then(
(response) => {
console.log(response);
let serverData = response.data.data;
let categories = [];
serverData.categoryDetails.forEach((data) => {
categories.push(data);
});
setcategories(categories);
},
);
} catch (e) {
}
}, [categories.length);
return (
<div>
{categories.map((sitems, ssindex) => {
<p>{sitems.name}</p>
<p>
{!readMore amp;amp;
sitems?.description?.substring(
0,
201
)}
{readMore amp;amp; sitems?.description}
<Link
to="#"
className="read-more-link"
onClick={() => {
setReadMore(!readMore);
}}
>
<>
{sitems?.description?.length >
201 amp;amp; linkName}
</>
</Link>
</p>
}
</div>
)};
Комментарии:
1. Вы хотите открывать какой-либо один
read more
за раз или несколько вариантов чтения??2. Я должен открывать по одному чтению за раз.
Ответ №1:
Я создал пример. Вы можете обратиться к этой ссылке на код
одновременно открывается несколько руд для чтения
Песочница: https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/read-multi.js
Note:
перейдите к /read-multi
codesandbox Browser
за один раз открывается руда для чтения
Песочница: https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/read-single.js
Note:
перейдите к /read-single
codesandbox Browser
Что вы делаете, так это сохраняете одно состояние для чтения большего количества всех категорий.
для множественного чтения
У вас должно быть отдельное состояние для каждой категории, и вы должны переключать это состояние только при нажатии кнопки readmore определенной категории. Для отдельного состояния чтения я взял логическое состояние массива размера категорий.
для однократного чтения
У вас должен быть readState index
открытый в данный момент, и если вы хотите открыть любой другой, затем сбросьте индекс readMore на новый индекс. в противном случае установите его равным -1, чтобы ничего не открывалось.
Комментарии:
1. @ Химаншу Сингх, у меня есть поле описания для каждой категории. Поэтому, если длина описания больше 201, я должен показать ссылку «Подробнее». Мой pblm заключается в том, что если я нажму любую ссылку для чтения в любом описании, откроется все остальные дополнительные сведения. И если я нажму меньше читать, все меньше читать будет работать.
2. Попробуйте это, вам нужно сохранить текущий открытый индекс, а не true или false. Если
current iterated category's index === current open index
, то он покажет все описание, в противном случае нет.3. прочитайте описание и просмотрите код, вы можете легко понять.
4. вы можете пометить это как ответ и закрыть вопрос
Ответ №2:
Вы должны проверять индекс и управлять состояниями с помощью своего индекса вместо использования одного логического значения. Вы должны легко исправить это с помощью состояний объекта, например const [readMore, setReadMore] = React.useState({isOpen: false, index: 0});
Но вместо реализации этого решения я бы создал новый компонент для этой части
<p>{sitems.name}</p>
<p>
{!readMore amp;amp;
sitems?.description?.substring(
0,
201
)}
{readMore amp;amp; sitems?.description}
<Link
to="#"
className="read-more-link"
onClick={() => {
setReadMore(!readMore);
}}
>
<>
{sitems?.description?.length >
201 amp;amp; linkName}
</>
</Link>
</p>
и верните его в функции map. Вы должны поместить свое состояние внутри нового компонента вместо использования внутри FullReport
компонента, и вы можете использовать его как логическое значение, как вы используете сейчас
const [readMore, setReadMore] = React.useState(false);
@Evren, согласно вашему предложению, мой отредактированный код находится здесь, разделенный на 2 компонента. но ссылки readmore не работают при нажатии сейчас.Пожалуйста, помогите мне исправить ошибку.
import React,{useState} from 'react';
export function FullReport(props) {
const [categories, setcategories] = React.useState([]);
React.useEffect(() => {
try {
axios
.get(
`/getReportDetails`
)
.then(
(response) => {
console.log(response);
let serverData = response.data.data;
let categories = [];
serverData.categoryDetails.forEach((data) => {
categories.push(data);
});
setcategories(categories);
},
);
} catch (e) {
}
}, [categories.length);
const ProfileItem = (sitems) => {
const [readMore, setReadMore] = React.useState(false);
return (
<div>
<p>
{!readMore amp;amp;
sitems?.description?.substring(
0,
201
)}
{readMore amp;amp; sitems?.description}
<Link to="#" className="read-more-link" onClick={() => setReadMore(!readMore);
}}>
{readMore ? "Read Less" : "Read more"}
</Link>
</p>
</div>
)}
return (
<div>
{categories.map((sitems, ssindex) => {
<ProfileItem {...sitems} />
})}
</div>
);
};
Я создал для вас рабочий пример. При рефакторинге вы не создавали новый компонент, вы просто создали функцию внутри компонента react. Здесь изолированная среда кода и код
import React from 'react';
export default function App(props) {
const categories = [{description:'123456789'},
{description:'123456789'},
{description:'123456789'},
{description:'123456789'}]
return (
<div>
{categories?.map((sitems, ssindex) => {
return <ProfileItem sitems={sitems} />
})}
</div>
);
};
export const ProfileItem = ({sitems}) => {
const [readMore, setReadMore] = React.useState(false);
return (
<div style={{border:'1px solid black', width: 300}} onClick={()=>setReadMore(!readMore)}>
<p >
{!readMore amp;amp;
sitems?.description?.substring(
0,
5
)}
{readMore amp;amp; sitems?.description}
</p>
</div>
)}
https://codesandbox.io/s/strange-sound-j93lv?file=/src/App.js
Комментарии:
1. Согласно вашему предложению, я отредактировал приведенный выше код, создав 2 компонента. но теперь при нажатии readmore buton не работает. можете ли вы сказать, где я ошибся?
2. Я обновил свой ответ @SreRoR