Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript (同构)路由和基于ajax的react组件的后端呈现_Javascript_Reactjs_React Router V4_Isomorphic Javascript - Fatal编程技术网

Javascript (同构)路由和基于ajax的react组件的后端呈现

Javascript (同构)路由和基于ajax的react组件的后端呈现,javascript,reactjs,react-router-v4,isomorphic-javascript,Javascript,Reactjs,React Router V4,Isomorphic Javascript,我正在尝试构建一个同构的react应用程序。我使用express作为后端。我有一个静态路由器,里面有一个应用程序组件。我捕获任何请求并使用renderToString,如下所示: (下面的代码不完整,可能有语法错误-未通过IDE运行) server.jsx: app.get("/*", (req, res) => { const itemIDs = ['myFirstItemID', 'mySecondItemID', 'myThirdItemID'] // fetched from

我正在尝试构建一个同构的react应用程序。我使用express作为后端。我有一个静态路由器,里面有一个应用程序组件。我捕获任何请求并使用renderToString,如下所示:

(下面的代码不完整,可能有语法错误-未通过IDE运行)

server.jsx:

app.get("/*", (req, res) => {
 const itemIDs =
 ['myFirstItemID', 'mySecondItemID', 'myThirdItemID'] // fetched from DB

 const renderedApp = 
 ReactDOM.renderToString(<StaticRouter> <App itemIDs=itemIDs /> </StaticRouter>);

 res.render("index", { renderedData: renderedApp });
 res.end();
}
app.get(“/*”,(req,res)=>{
常量项ID=
['myFirstItemID','mySecondItemID','myThirdItemID']//从数据库中获取
const renderapp=
renderToString();
res.render(“索引”{renderedData:renderedApp});
res.end();
}
App.jsx-仅渲染方法

render() {
    const renderedRoutes = this.props.itemIDs.map(itemID => (<Route path={itemID} render={() => <Item ItemID={itemID}/>} />)
    );
        return (
                    <Switch>
                        {renderedRoutes}
                        <Route component={ItemsContainer itemIDs=itemIDs} />
                    </Switch>
        )
    }
render() {
      const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)

      return (
        <div>
            {ItemSummaries}
          </div>
      )
 render() {
    return (
        <div>
          <Link to={"/" + this.props.itemId}>
        <h2>an item</h2>
    </Link>
        </div>
    )
render(){
const renderedRoutes=this.props.itemIDs.map(itemID=>(}/>)
);
返回(
{renderdRoutes}
)
}
ItemsContainer.jsx-仅渲染方法

render() {
    const renderedRoutes = this.props.itemIDs.map(itemID => (<Route path={itemID} render={() => <Item ItemID={itemID}/>} />)
    );
        return (
                    <Switch>
                        {renderedRoutes}
                        <Route component={ItemsContainer itemIDs=itemIDs} />
                    </Switch>
        )
    }
render() {
      const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)

      return (
        <div>
            {ItemSummaries}
          </div>
      )
 render() {
    return (
        <div>
          <Link to={"/" + this.props.itemId}>
        <h2>an item</h2>
    </Link>
        </div>
    )
render(){
const itemsumeries=this.props.itemIDs.map(itemId=>)
返回(
{项目摘要}
)
ItemPreview.jsx-仅渲染方法

render() {
    const renderedRoutes = this.props.itemIDs.map(itemID => (<Route path={itemID} render={() => <Item ItemID={itemID}/>} />)
    );
        return (
                    <Switch>
                        {renderedRoutes}
                        <Route component={ItemsContainer itemIDs=itemIDs} />
                    </Switch>
        )
    }
render() {
      const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)

      return (
        <div>
            {ItemSummaries}
          </div>
      )
 render() {
    return (
        <div>
          <Link to={"/" + this.props.itemId}>
        <h2>an item</h2>
    </Link>
        </div>
    )
render(){
返回(
项目
)
Item.jsx-组件添加和渲染

componentDidMount() {
axios.get("/api/items?itemID=" + this.props.itemID)
.then((data) => this.state.itemData = data);

render() {
    return (
        <div>
          //use itemData here
    </Link>
        </div>
    )
componentDidMount(){
axios.get(“/api/items?itemID=“+this.props.itemID”)
.然后((数据)=>this.state.itemData=data);
render(){
返回(
//在这里使用itemData
)
Client.jsx-提供给客户端(使用相同的App.jsx组件)

constmyroutedapp=()=>
(
);
ReactDOM.hydrate(,document.getElementById('root');
我觉得我的方法有点不对劲,但我不确定是什么。 我遇到的问题是:

  • ItemID仅在服务器内用于生成路由。一旦应用程序在客户端可用,我就不再有路由,因此BrowserRouter无法工作。我可以使用ajax获取路由,但这会导致在我获得所需数据之前进行初始渲染,这会导致始终看到ItemsContainer(默认路由)用于几个帧,无论我位于哪个URL
  • 对于依赖componentDidMount中的ajax来决定其render()内容(Item.jsx)的组件,我可以选择哪些选项来渲染字符串
  • 最后但并非最不重要的一点——这真的是一个好方法吗

因此,我发现解决第一个问题的一种方法是在初始索引页响应中呈现路由(在
标记中),然后让应用程序构造函数根据呈现的位置处理路由:

  • 如果由服务器渲染-使用传递的道具
  • 如果在浏览器中渲染-获取全局对象
下面是它在代码中的样子:

索引页(EJS模板)中的某处:

应用程序处理路线的方式:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = { routesData: this.isBrowser() ? globalRoutes : this.props.routesData }
    }

因此,我发现解决第一个问题的一种方法是在初始索引页响应中呈现路由(在
标记中),然后让应用程序构造函数根据呈现的位置处理路由:

  • 如果由服务器渲染-使用传递的道具
  • 如果在浏览器中渲染-获取全局对象
下面是它在代码中的样子:

索引页(EJS模板)中的某处:

应用程序处理路线的方式:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = { routesData: this.isBrowser() ? globalRoutes : this.props.routesData }
    }