One hidden layer is enough - if you have enough capacity in the net. That means that you usually have to make the net wider or add more layers.
The training of your net has trouble converging due to its small size and also that it is using a batch size of one.
Here are my modifications:

I backprop through your entire training data as a single batch on each epoch.
I made your two layer net wider.
I tried different optimizers - RMSprop seems to work the best.
I print the mean validation loss after training

import torch
import torch.nn as nn
import torch.optim as optim
from random import shuffle

class Net2(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(1,50)
        self.fc2 = nn.Linear(50,50)
        self.fc3 = nn.Linear(50,1)
    def forward(self, x):
        x = self.fc1(x).tanh()
        x = self.fc2(x).tanh()
        x = self.fc3(x)
        return x


class Net3(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(1,5)
        self.fc2 = nn.Linear(5,5)
        self.fc3 = nn.Linear(5,5)
        self.fc4 = nn.Linear(5,1)
    def forward(self, x):
        x = self.fc1(x).tanh()
        x = self.fc2(x).tanh()
        x = self.fc3(x).tanh()
        x = self.fc4(x)
        return x


net = Net2()

# optimizer = optim.SGD(net.parameters(), lr=1.0e-3)
# optimizer = optim.Adam(net.parameters(), lr=1.0e-3)
optimizer = optim.RMSprop(net.parameters(), lr=1.0e-2)

dataset = [(x,x.sin().mul(10.0)) for x in torch.linspace(0,10,400)]

for epoch in range(1600):
    shuffle(dataset)
    err=[]
    optimizer.zero_grad()
    for x,y in dataset:
        out = net(x.unsqueeze(0))
        err.append((out - y).pow(2.0))
    loss = torch.stack(err).mean()
    loss.backward()
    optimizer.step()
    print(f"[{epoch:4d}] {loss.data}")


#testing out the net
with torch.no_grad():
    val = []
    for z in torch.linspace(0,10,550):
        out = net(z.unsqueeze(0))
        val.append((out - z.sin().mul(10.0)).pow(2.0))
    loss = torch.stack(val).mean()
    print(f"validation loss = {loss}")