Навскидку:
1. В проектах по-хорошему использовать типизацию TypeScript, Flow. PropTypes в таком случае использовать не надо.
2. Тут в коде бессмысленное условие:
render() {
const { report = {} } = this.props;
return (
<Fragment>
<Head>
<title>Doctor problem with {report.doctor.name}</title>
</Head>
{report && <ReportDetail showDetailButton={false} data={report} />}
</Fragment>
);
}
report у вас существует всегда. Надеюсь понимаете, что пустой объект кастуется в true.
3. Про ESLint/TSLint уже писали.
4. Ваши редьюсеры не имеют ключей состояния. Какой-то запрос может быть в процессе, а ваши компоненты об этом не знают.
5. Логику работы с куками лучше вынести в actions.
6. Нет смысла разделять импорты отступами, просто соблюдайте очередность и смотрите пункт 3.
7. Компонент __app можно декомпозировать.
8. Неясно зачем тут геттер
get renderReports() { /* ... */ }
9. Для сортировки можно использовать меморизацию.
10.
handleChange = (e, key) => {
const value = e.target.value;
this.setState({
[key]: value,
});
};
<Input
id="outlined-name" // зачем?
placeholder="Problem Summary"
value={reportTitle}
onChange={e => handleChange(e, "reportTitle")}
/>
Можно заменить на:
handleChange = e => {
const { name, value } = e.target;
this.setState({
[name]: value,
});
};
<Input
id="outlined-name" // зачем?
placeholder="Problem Summary"
name="reportTitle"
value={reportTitle}
onChange={handleChange}
/>
11.
/components/ReportDetail/constants.js
зачем?
12. Где-то запросы в экшенах, где-то в компонентах.
Не знаком с next.js поэтому ничего объективного по организации кода сказать не могу, так как не до конца понимаю как этот фреймворк работает. Вижу, что авторизованных запросов пока нет. Запросы к API у вас будут происходить только на стороне клиента?