You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中如何将客户端组件状态传递给服务端组件?

问题:Next.js中客户端组件向服务端组件传递表单数据以修改XML文件

我用TypeScript和Next.js读写本地存储的包含<user>标签的.xml文件,现有三个核心组件:

  • UserTable组件:展示.xml中的<user>信息,负责数据展示
  • AddUserForm组件:客户端组件,负责输入新用户数据,数据存在formValues的useState变量中
  • AddNewUser组件:默认服务端组件,目前用模拟数据操作.xml文件

我需要把AddUserForm里的formValues传给AddNewUser组件,用输入的数据替换模拟数据来添加新<user>标签。试过useRouter和SSR等方法,都因为实现复杂没成功。


现有组件代码

AddUserForm组件(客户端组件)

'use client'
import Link from "next/link";
import { useState } from 'react';

const AddUserForm = () => {

  const [formValues, setFormValues] = useState({
    name: '',
    phone: '',
  });

  const handleChange = (e: any) => {
    const { id, value } = e.target;
    setFormValues((prevValues) => ({
      ...prevValues,
      [id]: value,
    }));
  };

  const handleSubmit = (e: any) => {
    e.preventDefault();
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <div>
            <label> Name </label>
            <input
                id="name"
                type="text"
                placeholder="Name"
                value={formValues.name}
                onChange={handleChange}
            />
        </div>

        <div>
            <label> Phone </label>
            <input
                id="phone"
                type="text"
                placeholder="Phone"
                value={formValues.phone}
                onChange={handleChange}
            />
        </div>

        <div>
          <Link href="/">
            <button>
              Go Back
            </button>
          </Link>
          
          <button type="submit">
            Add
          </button>
        </div>

      </form>
    </div>
  );
};

export default AddUserForm;

AddNewUser组件(服务端组件)

import fs from 'fs';
import { parseString, Builder  } from 'xml2js';

const AddNewUser = (props: any) => {
    const xmlFilePath = './public/user.xml';
    const xmlContent = fs.readFileSync(xmlFilePath, 'utf-8');
   
    parseString(xmlContent, { explicitArray: false }, (error: any, result: any) => {
        if (error) {
          console.error('Error parsing user.xml:', error);
        } else {
    
          const newUser = {
            $: {
              name: 'New User',
              phone: '123456789'
            },
          };
      
          result.root.users.user.push(newUser);
      
          // Converting updated XML object to XML string
          const builder = new Builder();
          const updatedXmlContent = builder.buildObject(result);
        
          // Updating the new XML content back to the file
          fs.writeFileSync(xmlFilePath, updatedXmlContent);
        }
      });      

    return (
      <div>
        
      </div>
    )
  }
  
  export default AddNewUser

解决方案:用Next.js API Route中转数据

客户端组件无法直接调用服务端组件的文件操作逻辑,API路由是最直接的解决方案:

步骤1:创建API路由处理XML写入

在app/api/add-user/route.ts创建API路由,把AddNewUser的文件操作逻辑迁移过来:

import fs from 'fs';
import { parseString, Builder } from 'xml2js';
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  try {
    const { name, phone } = await request.json();
    const xmlFilePath = './public/user.xml';
    const xmlContent = fs.readFileSync(xmlFilePath, 'utf-8');

    return new Promise((resolve, reject) => {
      parseString(xmlContent, { explicitArray: false }, (error, result) => {
        if (error) {
          console.error('解析XML出错:', error);
          return reject(NextResponse.json({ success: false, error: '解析XML失败' }, { status: 500 }));
        }

        // 兼容单个用户的情况,确保user是数组
        if (!Array.isArray(result.root.users.user)) {
          result.root.users.user = [result.root.users.user];
        }

        const newUser = {
          $: { name, phone }
        };
        result.root.users.user.push(newUser);

        const builder = new Builder();
        const updatedXmlContent = builder.buildObject(result);
        fs.writeFileSync(xmlFilePath, updatedXmlContent);

        resolve(NextResponse.json({ success: true }, { status: 200 }));
      });
    });
  } catch (error) {
    return NextResponse.json({ success: false, error: '服务器错误' }, { status: 500 });
  }
}

步骤2:修改AddUserForm组件提交逻辑

更新客户端组件的handleSubmit函数,通过POST请求把表单数据传给API路由:

'use client'
import Link from "next/link";
import { useState } from 'react';

const AddUserForm = () => {

  const [formValues, setFormValues] = useState({
    name: '',
    phone: '',
  });

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { id, value } = e.target;
    setFormValues((prevValues) => ({
      ...prevValues,
      [id]: value,
    }));
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      const response = await fetch('/api/add-user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formValues),
      });

      if (response.ok) {
        setFormValues({ name: '', phone: '' });
        alert('用户添加成功');
        // 可在此处跳转到用户列表页
      } else {
        alert('添加失败,请重试');
      }
    } catch (error) {
      console.error('提交出错:', error);
      alert('网络错误,请重试');
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <div>
            <label> 姓名 </label>
            <input
                id="name"
                type="text"
                placeholder="姓名"
                value={formValues.name}
                onChange={handleChange}
                required
            />
        </div>

        <div>
            <label> 电话 </label>
            <input
                id="phone"
                type="text"
                placeholder="电话"
                value={formValues.phone}
                onChange={handleChange}
                required
            />
        </div>

        <div>
          <Link href="/">
            <button type="button"> 返回 </button>
          </Link>
          
          <button type="submit"> 添加 </button>
        </div>
      </form>
    </div>
  );
};

export default AddUserForm;

步骤3:移除AddNewUser组件

现在文件操作逻辑已移到API路由,AddNewUser组件不再需要,可直接删除。


内容的提问来源于stack exchange,提问作者Ishaan_B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:05:08