На стороне сервера загрузите глобальный компонент с помощью Next.js в React
Тот факт, что я не могу найти никого, кто задает этот вопрос, вероятно, означает, что я что-то не понимаю в полной мере, или я ищу с неправильными ключевыми словами, поэтому, пожалуйста, не ломайте голову, если это глупый вопрос.
Я вставляю соответствующие части кода, но если вы хотите репозиторий с полным примером, вот оно. Полный вопрос будет внизу.
Вот моя структура папок:
server.js
/components
Layout.js
/pages
contact.js
server.js
// tells next which page to load
server.get("/contact/:id", (req, res) => {
const actualPage = "/contact"
const queryParams = {id: req.params.id}
app.render(req, res, actualPage, queryParams)
})
// api uri for grabbing contacts from the database
server.get("/api/contact/:id", (req, res) => {
Contact.findOne({first_name: req.params.id}, (error, contact) => {
if (error) return next(error)
res.status(200).json(contact)
})
})
pages/contact.js
const Contact = props => (
<Layout>
<h1>{props.contact.first_name} {props.contact.last_name}</h1>
</Layout>
)
// a static async call passes fetched data into the props
Contact.getInitialProps = async function (context) {
const {id} = context.query
const res = await fetch(`http://localhost:3000/api/contact/${id}`)
const contact = await res.json()
return {contact: contact}
}
components/Layout.js
const Layout = (props) =>
<div>
<div>
<Link href="/contact/John">
<a>John</a>
</Link>
<Link href="/contact/Jed">
<a>Jed</a>
</Link>
<Link href="/contact/Fred">
<a>Fred</a>
</Link>
</div>
{props.children}
</div>
Я пытаюсь выяснить, возможно ли динамический запрос к базе данных для построения навигации по документам в базе данных. Единственный способ, которым я могу думать, это сделать заново всю навигацию с каждым компонентом, но это кажется крайне ненужным. Опять же, если вы хотите попробовать код, вот мой пример репо.
1 ответ
Один из способов, который я могу придумать, - использовать собственный app.js и добавить componentDidMount
метод (он запускается только один раз), где вы можете получить все контакты, сохранить их в состоянии app.js и передать их страницам и компонентам.
_app.js
import React from 'react';
import App, { Container } from 'next/app';
export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
}
// store contacts in the state
state = {
contacts: undefined
};
componentDidMount() {
// get contacts and store them in the _app.js state
fetch('some-api/all-contacts-endpoint').then(contacts => {
this.setState({ contacts });
});
}
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<Component {...pageProps} contacts={this.state.contacts} />
</Container>
);
}
}
страниц /contact.js
// contacts will be inside props here
const Contact = props => (
<Layout contacts={props.contacts}>
<h1>
{props.contact.first_name} {props.contact.last_name}
</h1>
</Layout>
);
// a static async call passes fetched data into the props
Contact.getInitialProps = async function(context) {
const { id } = context.query;
const res = await fetch(`http://localhost:3000/api/contact/${id}`);
const contact = await res.json();
return { contact: contact };
};
компоненты /Layout.js
const Layout = ({ contacts = [] }) => (
<div>
<div>
{contacts.map(contact => (
<Link key={contact.id} href={`/contact/${contact.id}`}>
<a>{contact.name}</a>
</Link>
))}
</div>
{props.children}
</div>
);
Надеюсь это поможет!